Cześć, zagłębiam się w Jave i wątki. Cel jest taki, aby 1 wątek inkrementował zmienną a drugi dekrementował zmienną. Problem tutaj jest z synchronizacją. Generalnie wynik powinien być mniej więcej:
Wątek 1: 1
Wątek 2: 0
Wątek 1: 1
Wątek 2: 0
Wątek 1: 1
...
...
Próbuję to zadanie wykonać za pomocą wait() i notify(), niestety wynik jest błędny (albo zapada blokada w 2 wątkach albo wyświetla się błędna kolejność).
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainTest
{
public static volatile int a = 0;
public static void main(String[] args)
{
Runnable r1 = () ->
{
Thread.currentThread().setName("Watek 1");
for(int i = 0; i < 5; i++)
{
a++;
System.out.println("A1x = " + a );
synchronized(MainTest.class)
{
if(a > 0)
{
try
{
System.out.println(Thread.currentThread().getName() + " is waiting...");
MainTest.class.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
};
Runnable r2 = () ->
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread.currentThread().setName("Watek 2");
for(int i = 0; i < 5; i++)
{
synchronized (MainTest.class)
{
if(a > 0)
{
System.out.println("WAKE UP");
a--;
System.out.println("A2x = " + a );
MainTest.class.notify();
}
}
}
};
ExecutorService exec = Executors.newCachedThreadPool();
exec.submit(r1);
exec.submit(r2);
exec.shutdown();
try
{
exec.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e)
{
///
}
}
}
Jak sobie wyobrażam, że to powinno działać:
: A
W r1 następuje a++ [a = 1], wchodzi w blok synchronized i w ifa wywołuje wait().
w r2 wchodzi w blok synchronized i ifa, następuje a-- [a = 0] następnie wywoływane jest notify, budzi się r1.
goto A