java多線程編程之應用Synchronized塊同步變量。本站提示廣大學習愛好者:(java多線程編程之應用Synchronized塊同步變量)文章只能為提供參考,不一定能成為您想要的結果。以下是java多線程編程之應用Synchronized塊同步變量正文
上面的代碼演示了若何同步特定的類辦法:
package mythread;
public class SyncThread extends Thread
{
private static String sync = "";
private String methodType = "";
private static void method(String s)
{
synchronized (sync)
{
sync = s;
System.out.println(s);
while (true);
}
}
public void method1()
{
method("method1");
}
public static void staticMethod1()
{
method("staticMethod1");
}
public void run()
{
if (methodType.equals("static"))
staticMethod1();
else if (methodType.equals("nonstatic"))
method1();
}
public SyncThread(String methodType)
{
this.methodType = methodType;
}
public static void main(String[] args) throws Exception
{
SyncThread sample1 = new SyncThread("nonstatic");
SyncThread sample2 = new SyncThread("static");
sample1.start();
sample2.start();
}
}
運轉成果以下:
method1
staticMethod1
看到下面的運轉成果許多讀者能夠覺得驚異。在下面的代碼中method1和staticMethod1辦法應用了靜態字符串變量sync停止同步。這兩個辦法只能有一個同時履行,而這兩個辦法都邑履行014行的無窮輪回語句。是以,輸入成果只能是method1和staticMethod1個中之一。但這個法式將這兩個字符串都輸入了。
湧現這類成果的情願很簡略,我們看一下012行就曉得了。本來在這一即將sync的值轉變了。在這裡要說一下Java中的String類型。String類型和Java中其他的龐雜類型分歧。在應用String型變量時,只需給這個變量賦一次值,Java就會創立個新的String類型的實例。以下面的代碼所示:
String s = "hello";
System.out.println(s.hashCode());
s = "world";
System.out.println(s.hashCode());
在下面的代碼中。第一個s和再次賦值後的s的hashCode的值是紛歧樣的。因為創立String類的實例其實不須要應用new,是以,在同步String類型的變量時要留意不要給這個變量賦值,不然會使變量沒法同步。
因為在012行曾經為sync創立了一個新的實例,假定method1先履行,當method1辦法履行了013行的代碼後,sync的值就曾經不是最後誰人值了,而method1辦法鎖定的依然是sync變量最後的誰人值。而在這時候,staticMethod1正好履行到synchronized(sync),在staticMethod1辦法中要鎖定的這個sync和method1辦法鎖定的sync曾經不是一個了,是以,這兩個辦法的同步性曾經被損壞了。
處理以上成績的辦法固然是將012行去失落。在本例中加上這行,只是為了解釋應用類變量來同步辦法時假如在synchronized塊中將同步變量的值轉變,就會損壞辦法之間的同步。為了完全防止這類情形產生,在界說同步變量時可使用final症結字。如將下面的法式中的005行可改成以下情勢:
private final static String sync = "";
應用final症結字後,sync只能在界說時為其賦值,而且今後不克不及再修正。假如在法式的其他處所給sync賦了值,法式就沒法編譯經由過程。在Eclipse等開辟對象中,會直接在毛病的處所給出提醒。
我們可以從兩個角度來懂得synchronized塊。假如從類辦法的角度來懂得,可以經由過程類變量來同步響應的辦法。假如從類變量的角度來懂得,可使用synchronized塊來包管某個類變量同時只能被一個辦法拜訪。不論從哪一個角度來懂得,它們的本質都是一樣的,就是應用類變量來取得同步鎖,經由過程同步鎖的互斥性來完成同步。
留意:在應用synchronized塊時應留意,synchronized塊只能應用對象作為它的參數。假如是簡略類型的變量(如int、char、boolean等),不克不及應用synchronized來同步。