2016-10-02 85 views
1

兩類因子和加法確認同步概念

因子具有VAL變量,這意味着它在多個線程共享的(在目前的應用中,我們使用的是兩個線程)。

另外類有一個添加變量,它也在多個線程之間共享,因爲它在因子類中實例化。

我的問題是

  1. 如果synchronized(this)被使用,這意味着任何兩個線程將鎖定因素實例,並增加VAL變量的值,直到循環退出。 所以synchronized(this)這裏意味着我們不應該使用任何其他實例變量。我們只能在synchronized塊中使用因子實例的變量嗎?

  2. if synchronized(addition)這裏意味着我們只需要使用添加變量而不是因子實例類的val變量?

關於這個同步塊存在很大的困惑。 我明白的是同步塊會鎖定對象的實例,並防止操作並使其安全。但使用不同的實例真的意味着它應該只保護特定的實例變量而不是其他任何實例變量?

class Factor implements Runnable 
{ 

int val = 0; 
Addition addtion = new Addition(); 

@Override 
public void run() 
{ 

    currInsLock(); 
    diffInsLock(); 
} 

// locking on the current instance which is this 
// we will use synchronized(this) 

public void currInsLock() 
{ 
    synchronized (this) 
    { 
     for(int i=0;i<100;i++) 
     { 
       try 
        { 
        Thread.sleep(100); 
        } 
       catch (InterruptedException e) 
       { 
         e.printStackTrace(); 
       } 
     System.out.println(Thread.currentThread().getName()+"---val value lock on this obj -->"+val++); 

     } 
    } 
} 



// locking on the different instance 
public void diffInsLock() 
{ 
    synchronized (addtion) 
    { 

     for(int i=0;i<100;i++) 
     { 
       try 
        { 
        Thread.sleep(100); 
        } 
       catch (InterruptedException e) 
       { 
         e.printStackTrace(); 
       } 
     System.out.println(Thread.currentThread().getName()+"---val value lock on addition obj -->"+val++); 
     System.out.println(Thread.currentThread().getName()+"---add value lock on addition obj -->"+addtion.add++); 
     } 
    } 
} 

} 

類操作& ConcurrentDoubt:特定對象上

public class Addition 
{ 
    public int add=0; 

} 

public class ConcurrentDoubt { 

public static void main(String[] args) 
{ 
    Factor factor=new Factor(); 

    Thread thread1=new Thread(factor); 
    Thread thread2=new Thread(factor); 

    thread1.start(); 
    thread2.start(); 

} 
} 

回答

1

號同步不鎖定該對象,並且不阻止您使用同步塊內的其他對象。

在一個對象上進行同步可以防止另一個線程同時嘗試在同一個對象上進行同步,直到第一個線程退出同步塊爲止。您需要決定如何將訪問同步到某種可變狀態。它可能是包含該狀態的對象或任何其他對象。重要的是訪問這個可變狀態的所有線程都使用相同的對象進行同步。

在發佈的代碼中,addtion.add可變狀態會得到適當的保護,因爲所有線程在同一個對象上同步,以訪問該對象,即addtion

val可變狀態未得到適當的保護,因爲一個方法在this上同步以訪問它,而另一個方法在addtion上同步。因此,如果一個線程調用第一個方法而另一個調用第二個方法,則它們都會嘗試增加並同時讀取相同的值。

+0

根據答案提供的同步(加法)是正確的,因爲加法,加上mutable狀態是p謹慎守衛。由於增量操作在同步(加法)中使用,因此val可變狀態未得到適當的保護,這意味着val變量在同步(加法)中被訪問。如果我只在同步內使用val變量(this)並且只在同步內添加變量(加法),那麼這兩個變量都會被正確保護,但是有什麼區別 – amt14779

0

爲了更好地理解同步概念,閱讀synchronized methods甲骨文教程文章和intrinsic locks

synchronized`關鍵字適用於方法/代碼塊,而不是變量。

synchronized(this)表示我們不應該使用任何其他實例變量。

這是錯誤的。 synchronized(this)允許訪問其中一個線程並保持其他線程等待。但同時,成員變量對象可以通過其他方法修改。方法1:您獲得鎖synchronized (this)但您沒有修改成員變量:addition。您可以使用其他一些方法,它們可以修改Factor對象的成員變量(包括additionval)。

方法2:您已通過synchronized (addtion)獲取鎖定。現在添加不能被其他線程修改,試圖訪問這個代碼塊的附加變量。您使用錯誤的addition來修改val,因爲其他線程可以自由修改val變量(這是原始的而不是對象)。

如果要保護變量(,類型爲對象),請同步該特定變量而不是整個對象。

在您的應用程序中定義細粒度的鎖。

但是,使用不同的實例真的意味着它應該只保護特定的實例變量而不是任何其他實例變量?

​​請確保:同一對象上的兩個同步方法調用不可能交錯。但如果你有差別的實例,除非該變量爲static這些實例可以單獨修改數據和方法static synchronized

看一看相關SE的問題:

What does 'synchronized' mean?

Synchronization vs Lock

Avoid synchronized(this) in Java?