Threads的新功能。
我有2个线程,希望它们交替使用一种方法。因此线程1执行该方法,然后等待。然后线程2唤醒线程1并执行该方法。然后线程1唤醒线程2并执行方法等。 但是我莫名其妙地陷入了僵局,我也不明白为什么。
public class NewT extends Thread{
public void print(NewT x)
{
synchronized(this)
{
System.out.println("x"+x);
notifyAll();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void run()
{
for(int i=0;i<10;i++)
{
print(this);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
NewT one = new NewT();
NewT two = new NewT();
one.start();
two.start();
}
}
答案 0 :(得分:4)
由于synchronized
在this
上,每个线程都在锁定自己的对象,实际上没有同步;他们正在等待一个永远不会发生的事件。
更新:
正如某人指出的那样,仅使用公共lock
对象是不够的,因为两个线程最终都将等待。
这是一个解决方案:
private static Object lock = new Object();
private static NewT previous;
public static void print(NewT x) throws InterruptedException
{
synchronized(lock) {
while (previous == x) {
lock.wait();
}
System.out.println("x"+ x);
previous = x;
lock.notifyAll();
}
}
答案 1 :(得分:0)
Wait()
,notify()
和notifyAll()
可以正常工作。在您的情况下,您是在通知自己(相同的线程实例)并等待不确定的时间。结果,JVM无法在2个条目后打印。
示例代码:
package ThreadsTricks;
/**
*
* @author pcu
*/
public class PrintOddEven {
boolean odd;
int count = 1;
int MAX = 20;
public void printOdd() {
synchronized (this) {
while (count < MAX) {
System.out.println("Checking odd loop");
while (!odd) {
try {
System.out.println("Odd waiting : " + count);
wait();
System.out.println("Notified odd :" + count);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Odd Thread :" + count);
count++;
odd = false;
notify();
}
}
}
public void printEven() {
try {
// Thread.sleep(1000);
} catch (Exception e1) {
e1.printStackTrace();
}
synchronized (this) {
while (count < MAX) {
System.out.println("Checking even loop");
while (odd) {
try {
System.out.println("Even waiting: " + count);
wait();
System.out.println("Notified even:" + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even thread :" + count);
count++;
odd = true;
notify();
}
}
}
public static void main(String[] args) {
PrintOddEven oddEven= new PrintOddEven();
oddEven.odd = true;
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
oddEven.printEven();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
oddEven.printOdd();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (Exception e) {
e.printStackTrace();
}
}
这是我的第一个答案,如果有任何疑问,请告诉我。
答案 2 :(得分:0)
我在您的代码中看到的问题是您没有要锁定的共享对象,并且您的一个线程将永远等待(因为另一个线程已完成其活动并继续前进...)。我个人认为这里没有僵局。
这应该会有所帮助,但是我建议使用java.util.concurrent
软件包以获得更好的选择。我个人不建议使用wait
和notify
/ notfiyAll
import java.time.Instant;
public class AlternatingThreads {
public static void main(String[] args) {
Object lock = new Object();
NewT one = new NewT(lock);
NewT two = new NewT(lock);
one.start();
two.start();
}
public static class NewT extends Thread {
private Object lock;
public NewT(Object lock) {
this.lock = lock;
}
public void print(NewT x) {
synchronized (lock) {
System.out.println(Instant.now().getNano() + "ns x-" + x);
lock.notifyAll();
try {
// timeout depends on how long you need for the activity to complete.
lock.wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
for (int i = 0; i < 10; i++) {
print(this);
}
System.out.println(Instant.now().getNano() + "ns Final-" + this);
}
}
}
这将产生以下输出
573000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
576000000ns x-Thread[Thread-2,5,main]
576000000ns x-Thread[Thread-1,5,main]
577000000ns x-Thread[Thread-2,5,main]
577000000ns x-Thread[Thread-1,5,main]
577000000ns x-Thread[Thread-2,5,main]
577000000ns x-Thread[Thread-1,5,main]
577000000ns x-Thread[Thread-2,5,main]
577000000ns Final-Thread[Thread-1,5,main]
677000000ns Final-Thread[Thread-2,5,main]
Process finished with exit code 0
注意:如果没有100ms的超时,线程2将永远等待。