2015-10-14 157 views
0

任何人都可以告訴我如何使用2個線程同時訪問一個方法,該方法有2個參數和2個同步塊。我想要的是,一個線程執行第一個同步塊,另一個線程執行第二個同步塊。同時使用兩個線程訪問兩個同步塊

public class myThread{ 

public static class TwoSums implements Runnable{ 
    private int sum1 = 0; 
    private int sum2 = 0; 

    public void add(int a, int b){ 
     synchronized(this){ 
      sum1 += a; 
      String name = Thread.currentThread().getName(); 
      System.out.println("Thread name that was accessing this code 1 : "+name); 
     } 

     synchronized(this){ 
      sum2 += b; 
      String name = Thread.currentThread().getName(); 
      System.out.println("Thread name that was accessing this code 2 : "+name); 
     } 
    } 

    @Override 
    public void run() { 
     add(10,20); 
    } 
} 

public static void main(String[] args) { 
    TwoSums task = new TwoSums(); 

    Thread t1 = new Thread(task, "Thread 1"); 
    Thread t2 = new Thread(task, "Thread 2"); 

    t1.start(); 
    t2.start(); 
} 

}

此代碼含有一些代碼:由任何線程和同步塊不作任何異常http://tutorials.jenkov.com/java-concurrency/race-conditions-and-critical-sections.html

+1

第二個線程不能得到第二synchronized塊不先執行第一個... – immibis

+2

把你的方法到2點不同的方法。 –

+0

所以這意味着我不能在一種方法中訪問2線程的同步塊? – Okem

回答

0

所述指令被處理順序。下面的代碼做你問什麼,但看起來只是作爲一個練習,沒有任何真正有意義的應用

public static class TwoSums implements Runnable { 
    private int sum1 = 0; 
    private int sum2 = 0; 

    public void add(int a, int b) { 
     if ("Thread 1".equals(Thread.currentThread().getName())) { 
      synchronized (this) { 
       sum1 += a; 
       String name = Thread.currentThread().getName(); 
       System.out.println("Thread name that was accessing this code 1 : " + name); 
      } 
     } 
     if ("Thread 2".equals(Thread.currentThread().getName())) { 
      synchronized (this) { 
       sum2 += b; 
       String name = Thread.currentThread().getName(); 
       System.out.println("Thread name that was accessing this code 2 : " + name); 
      } 
     } 
    } 

    @Override 
    public void run() { 
     add(10, 20); 
    } 
} 
0

爲了實現這一目標(我不打算討論,如果你正在做的是對還是錯了,因爲我想,你只是在學習如何工作),你需要使用ReentranLock接口及其實現鎖類:

Lock lock = new ReentrantLock(); 

你應該在你TwoSum類中聲明該對象,並使用內部的鎖定對象你的添加方法。 ReentrantLock接口有一個名爲tryLock的方法,它將嘗試獲取被調用對象的鎖定,如果成功或否則返回布爾值true。所以對於第一個線程它將返回true,但對於第二個線程它將返回false。因此,所有你需要把一個驗證

if(lock.tryLock()) //Execute block code 1 
else // Execute block code 2