Резьба t1 вступает в тупик после того, как
wait()
попал в поле зрения. хотя естьnotify()
в t2. Код вступает в тупик. Не получать заявка на печать - «После того как ожидание освобождено ::::»Wait and Notify Ситуация с тупиком в JavaЯ вижу оба потока, конкурирующие за приобретение монитора в
counterAdd()
. Поэтому я предполагаю, что уведомление будет работать.package com.java.thread.practice; public class WaitAndNotify4 { int counter = 0; /* CounterAdd() is to be accessed by both t1 and t2. If not synchronized not giving consistent output. */ synchronized int counterAdd(){ return counter++; } public static void main(String[] args) throws InterruptedException{ // Creating method to call the threads. WaitAndNotify4 andNotify4 = new WaitAndNotify4(); andNotify4.testRaceCondition(); } private void testRaceCondition() throws InterruptedException { // Thread t1 created and launched. Thread t1 = new Thread(new Runnable(){ @Override public void run() { for(int i=0; i<5; i++){ synchronized(this){ if(i== 1){ System.out.println("Calling wait after count 1"); try { // Assuming that this wait will be resumed by notify in t2. wait(); System.out.println("After wait is released :::: "); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } counterAdd(); } } }); Thread t2 = new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub for(int i=0; i<5; i++){ if(i==2){ synchronized(this){ System.out.println("Before releasing the counter :::::"); notify(); System.out.println("After releasing the counter :::::"); } } counterAdd(); } } }); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(" Sum value is found as ::::: "+counter); } }
ответ
Вы синхронизации на различных объектах. В первом случае на объекте t1
, во втором - на t2
, в способе counterAdd
на andNotify4
. Чтобы разместить блокировку на andNotify4
все время, вам нужно сделать что-то подобное.
public class Main {
private int counter = 0;
synchronized int counterAdd() {
return counter++;
}
public static void main(String[] args) throws InterruptedException {
Main andNotify4 = new Main();
andNotify4.testRaceCondition();
}
private void testRaceCondition() throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
synchronized (Main.this) {
if (i == 1) {
System.out.println("Calling wait after count 1");
try {
Main.this.wait();
System.out.println("After wait is released :::: ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
counterAdd();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
if (i == 2) {
synchronized (Main.this) {
System.out.println("Before releasing the counter :::::");
Main.this.notify();
System.out.println("After releasing the counter :::::");
}
}
counterAdd();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(" Sum value is found as ::::: " + counter);
}
}
Большое спасибо. Он решает проблему и очищает концепцию. Если вы также можете пролить свет на часть. « Я вижу оба потока, конкурирующие за приобретение монитора в counterAdd(). Поэтому я предполагал, что уведомление будет работать». –
Если они представляют собой два разных потока со ссылками на разные объекты, counterAdd() должен печатать 10 всегда без синхронизированного ключевого слова. –
Не используйте форматирование цитаты для текста, который не цитируется. – EJP