2013-07-19 83 views
0

如果我們使用什麼對象來獲取同步塊上的鎖,是否真的很重要?使用不同對象的同步塊

例如,我有2個代碼片段,如下所示。 兩者產生相同的輸出。我只改變用於該同步塊上獲得鎖

代碼對象物1:

package test.thread.synchronization; 
public class Run1 implements Runnable{ 
String ts1=null; 
public Run1(String ts1){ 
    this.ts1=ts1; 
} 
    @Override 
public void run() { 
    // TODO Auto-generated method stub 
    run1Print(); 
} 
public void run1Print(){ 
    synchronized(ts1){ 
    for(int i =0;i<10;i++){ 
     System.out.println("run1Print: "+Thread.currentThread().getName()+":"+i); 
    try{ 
    Thread.sleep(1000); 
    }catch(InterruptedException e){ 
     e.printStackTrace(); 
    } 
    } 
    } 
} 
} 

====

package test.thread.synchronization; 
public class Run2 implements Runnable{ 
String ts1=null; 
public Run2(String ts1){ 
    this.ts1=ts1; 
} 
@Override 
public void run() { 
    // TODO Auto-generated method stub 
    run2Print(); 
} 
public void run2Print(){ 
    synchronized(ts1){ 
// System.out.println("Decrement"); 

    for(int i =0;i<10;i++){ 
     System.out.println("run2Print: "+Thread.currentThread().getName()+":"+i); 
    try{ 
    Thread.sleep(1000); 
    }catch(InterruptedException e){ 
     e.printStackTrace(); 
    } 
    } 
    } 
} 
} 

=====

package test.thread.synchronization; 
public class Ts1 { 
public static void main(String[] args) { 

    // Ts1 ts1 = new Ts1(); 
    String ts1 = ""; 
    Run1 tr1 = new Run1(ts1); 
    Run2 tr2 = new Run2(ts1); 
    Thread t1 = new Thread(tr1); 
    Thread t2 = new Thread(tr2); 
    t1.start(); 
    t2.start(); 
} 

}

代碼2:

package test.thread.synchronization; 
public class Run1 implements Runnable{ 
Ts1 ts1=null; 
public Run1(Ts1 ts1){ 
    this.ts1=ts1; 
} 
@Override 
public void run() { 
    // TODO Auto-generated method stub 
    run1Print(); 
} 
public void run1Print(){ 
    synchronized(ts1){ 
    for(int i =0;i<10;i++){ 
     System.out.println("run1Print: "+Thread.currentThread().getName()+":"+i); 
    try{ 
    Thread.sleep(1000); 
    }catch(InterruptedException e){ 
     e.printStackTrace(); 
    } 
    } 
    } 
} 
} 

======

package test.thread.synchronization; 
public class Run2 implements Runnable{ 
Ts1 ts1=null; 
public Run2(Ts1 ts1){ 
    this.ts1=ts1; 
} 
@Override 
public void run() { 
    // TODO Auto-generated method stub 
    run2Print(); 
} 
public void run2Print(){ 
    synchronized(ts1){ 
// System.out.println("Decrement"); 
    for(int i =0;i<10;i++){ 
     System.out.println("run2Print: "+Thread.currentThread().getName()+":"+i); 
    try{ 
    Thread.sleep(1000); 
    }catch(InterruptedException e){ 
     e.printStackTrace(); 
    } 
    } 
    } 
} 
} 

======

package test.thread.synchronization; 
public class Ts1 { 
public static void main(String[] args) { 

    Ts1 ts1 = new Ts1(); 
    //String ts1 = ""; 
    Run1 tr1 = new Run1(ts1); 
    Run2 tr2 = new Run2(ts1); 
    Thread t1 = new Thread(tr1); 
    Thread t2 = new Thread(tr2); 
    t1.start(); 
    t2.start(); 
} 

} 
+1

不要在字符串文字上同步。使用一個專用的最終對象作爲你的鎖(如'private final Object lock = new Object();')。字符串文字是合併的,因此''「'是虛擬機中所有代碼的唯一對象。如果每個人都在''「上同步,那麼這就是死鎖的祕訣。 –

回答

2

對象類型並不重要,但你應該在唯一的final對象上進行同步,否則可能會無意中讓兩個線程在兩個不同的對象上同步。