前两天做java作业,碰到这样一道题目:
准备两个线程对象,启动之后,每个线程执行3次之后再由下一个线程继续执行3次。
线程1执行1次
线程1执行2次
线程1执行3次
线程2执行1次
线程2执行2次
线程2执行3次
—————–
线程1执行1次
线程1执行2次
线程1执行3次
线程2执行1次
线程2执行2次
线程2执行3次
—————-
线程1执行1次
线程1执行2次
线程1执行3次
线程2执行1次
线程2执行2次
线程2执行3次
。。。。。。
然后以下是我对应的程序代码:
public class Work {
private int num;
private int temp;//切换线程
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getTemp() {
return temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public synchronized void working1(){
String name=Thread.currentThread().getName();
try{
if (num < 3){
for (int i=0;i<3;i++){
num++;
System.out.println(name+"执行"+num+"次");
}
if (num==3){
this.notifyAll();
}
}else if (num==3){
num=0;
this.wait();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public class ThreadA implements Runnable{
private Work work;
public ThreadA(Work work){
this.work=work;
}
@Override
public void run() {
for (int i=0;i<9;i++){
work.working1();
}
}
}
public class Ex2 {
public static void main(String[] args) {
Work work=new Work();
work.setNum(0);
work.setTemp(0);
Thread a=new Thread(new ThreadA(work),"线程1");
a.start();
Thread b=new Thread(new ThreadA(work),"线程2");
b.start();
}
}
但是在程序运行之后,发现“线程1”和“线程2”并不能正常结束
但是输出结果是正确的
经过调试发现应该是两个线程在执行过程中都被wait()所导致的。
if (num < 3){
for (int i=0;i<3;i++){
num++;
System.out.println(name+"执行"+num+"次");
}
if (num==3){
this.notifyAll();
}
}else if (num==3){
num=0;
this.wait();
}
每当num==3时,当前线程就会进入wait()状态。因为else if(num==3)进入时,导致notifyALL()无法执行,所以两条线程都会wait(),导致子线程无法结束,程序无法结束
修改为:
if (num==3){
// this.notifyAll();
this.wait();
}
}else if (num==3){
num=0;
// this.wait();
this.notifyAll();
问题解决。
但是其实这个程序还是有问题的。
在生产者消费者问题中,正确的流程应该是:
线程A生产 > 生产完成 > 通知线程B > 线程A进入wait > 线程B开始消费 > 消费完成 > 通知线程A开始生产 > 线程B进入wait > 线程A开始生产
以这样的一个方式开始循环。
但再这个程序中,流程是不规范的:
线程A执行 > 线程A执行 > 线程A开始沉睡 > 通知其他所有线程开始 > 线程B和线程A开始 > 线程A等待线程B结束 ……..
也就是说,线程B还没接说,线程A就还是醒了,但是因为线程B加了锁,所以A要等待B执行,效果虽然能达到,但是当线程多了以后,比如多了一个C线程,很可能会造成A和C的争抢,导致程序出现bug。
今天的文章生产者消费者线程池_当我们需要所有线程都执行到某一处分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/89409.html