Java代码-线程相互阻塞
我不熟悉多线程。我正在尝试编写一个有两个线程的程序。一个线程打印奇数,然后使用wait()放弃监视器锁,类似地,另一个线程打印偶数,并在打印数字后放弃锁Java代码-线程相互阻塞,java,multithreading,Java,Multithreading,我不熟悉多线程。我正在尝试编写一个有两个线程的程序。一个线程打印奇数,然后使用wait()放弃监视器锁,类似地,另一个线程打印偶数,并在打印数字后放弃锁 我有四节课 Odd.java(打印1-100之间的奇数) 偶数.java(打印1-100之间的偶数) java(具有打印奇数和偶数的逻辑) OEApp.java(启动线程的主类) 问题-我的代码在大多数情况下都按预期工作,即按顺序打印数字1到100。两条线轮流穿。但我注意到有一个bug,有时偶数线程会先调度,然后低于输出 2 ******
我有四节课
2 **********
1 ###############################
在没有打印任何内容之后,似乎出现了死锁情况。我不知道为什么。请帮助我理解这一点
public class SomeMaths {
public synchronized void printOdd(){
for( int i=1;i<=100;i++){
if(i%2 !=0) {
System.out.println(i + " ###############################");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
public synchronized void printEven(){
for(int i=1;i<=100;i++){
if(i%2 ==0){
System.out.println(i +" **********");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
我相信它是这样运作的:
您使用同步关键字的目的是什么?
它只能保证您的函数不会同时运行多次 我假设您希望一个线程通知另一个线程?是这样吗?
但是如果在等待发生之前调用了通知,该怎么办 您知道您可以使用调试器来查看每个线程,从而知道每个线程被卡住的位置吗 请记住,一旦调用了start,您就无法知道哪个线程将有cpu时间 此外,您正在尝试同步两个线程(通过使用notify/wait机制),但是还有其他机制将被证明更简单(例如,信号灯:每个线程都有自己的信号灯,获取自己的信号灯,并释放另一个信号灯;将每个信号灯初始化为1,它将顺利运行) 附言:
- 我被迫发布一个答案,但它应该是一个评论;对不起
- 为什么要同时使用runnable和thread接口呢?此外,偶数类已经是线程了,所以没有必要再次包装它
- 看
偶数
扩展线程
,为什么要使用新线程(新偶数(sm))
用另一个线程包装它?我正要问解决方案是什么,但后来意识到问题不要求解决方案,只要求解释原因,所以我加1。“使用synchronize关键字的目的是什么?”首先,在使用notify()
和wait()
时需要它,所以这是一个愚蠢的问题。“为什么同时使用runnable和thread接口?”因为建议实现runnable
,而不是扩展thread
,这意味着您将在代码中“使用”这两个接口。请参阅。您对“为什么同时使用runnable和thread接口?"有点奇怪:我没有建议使用这两种方法中的任何一种,但问了使用这两种方法的原因。评论回答说:因为建议实现Runnable
,然后将其作为Thread
构造函数的参数,也就是说,您将同时使用这两种方法。我同意Runnable是最好的方法,但正如我所说的ned我对线程是新手,我只是在两种方法之间玩。
public class Odd implements Runnable {
SomeMaths sm;
public Odd(SomeMaths sm){
this.sm = sm;
}
@Override
public void run(){
sm.printOdd();
}
}
public class Even extends Thread {
SomeMaths sm;
public Even(SomeMaths sm){
this.sm = sm;
}
@Override
public void run(){
sm.printEven();
}
}
public class OEApp {
public static void main(String[] args) {
SomeMaths sm = new SomeMaths();
Thread odd = new Thread(new Odd(sm));
Thread even = new Thread(new Even(sm));
odd.start();
even.start();
try {
odd.join();
even.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}