2015-10-14 4 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

Второго поток не может добраться до второго синхронизированного блока без выполнения первого первого ... – immibis

+2

Разделите ваш метод на 2 различные методы. –

+0

, значит, я не могу получить доступ к 2 синхронизированным блокам с 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, если оно было успешным или false в противном случае. Поэтому для первого потока он вернет true, но для второго он вернет false. Так что все, что вам нужно поставить это проверка

if(lock.tryLock()) //Execute block code 1 
else // Execute block code 2 
Смежные вопросы