我想打印“ping”“pong”,它们在同一个类中,但方法不同,使用同步块打印5次。
问题是它在打印乒乓一次后就停止了。
如何打印乒乓球5次?
我想我把notifyAll()和wait()放在了正确的位置。
打印结果
ping
pong
这是我的主类
public class ThreadTest2 {
public static void main(String[] args) throws {
Thread thread1 = new Thread(() -> {
forLoop("a");
});
Thread thread2 = new Thread(() -> {
forLoop(null);
});
thread1.setPriority(10);
thread2.setPriority(1);
thread1.start();
thread2.start();
}
static void forLoop(String target) {
AA aa = new AA();
try {
for(int i=0; i<5; i++){
if(target != null){
aa.ping();
}
else{
aa.pong();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这是我的乒乓球课
public class AA {
Thread thread;
public void ping() throws InterruptedException {
synchronized (this) {
System.out.println("ping");
wait();
notifyAll();
}
}
public void pong() throws InterruptedException {
synchronized (this) {
System.out.println("pong");
notifyAll();
wait();
}
}
}
谢谢你,谢谢你
ping
pong
ping
pong
ping
pong
ping
pong
ping
pong
2条答案
按热度按时间sz81bmfz1#
问题是它在打印乒乓一次后就停止了。
我真的不喜欢这些学术性的问题。让两个线程彼此锁步正是你不想做的,因为线程被设计为异步运行,协调频率更低。
您的代码有许多问题:
forloop()
方法都会创建一个新的AA
示例。因为您在每个线程中都调用它,所以每个线程都将锁定并等待AA
的 * 不同 * 示例,这样它们就看不到另一个线程的notifyAll()
,并且总是死锁。您需要创建一个AA
,并将同一个示例传递给两个for循环。wait()
之前 * 调用notifyAll()
,否则ping线程可能会在 * 唤醒pong线程之前 * 等待,从而导致死锁。boolean firstPrinted
字段,并在println(...)
之后将其设置为true
,然后让pong执行如下操作:aa.oneMoreNotify()
的调用:其他意见:
thread.setPriority(...)
实际上做得很少,除非你有非常CPU绑定的计算循环。这些应该被删除。catch (InterruptedException e)
时,你应该立即调用Thread.currentThread().interrupt()
作为一个好的模式。String target
而不是boolean
是一种奇怪的模式。message.equals("pong")
。AA
中的Thread
字段未使用,会造成混淆。f1tvaqid2#