sleep()函数的一个小细节,改变线程的运行顺序

这个问题在写的时候,我开始的时候没有加上sleep()函数,发现在运行的时候,都是生产者先生产20个,然后消费者消费20个,然后再生产20个,这样,这就恨不符合实际情况。但是我发现视频中讲解的时候加上了sleep函数,我就照猫画虎的加上了,加上以后发现结果就正确了。因此怀疑问题出在了sleep() 函数上。通过查看这个博文:(22条消息) 深入理解Thread.sleep()的意义_椰子真的是只猫-CSDN博客_thread.sleep

大致意思就是:假设有两个线程,A和B,windows在运行的时候,会先随机运行一个,例如是A。如果A很简单,会很快运行完,那么就会先全部运行完A以后,再去运行B,如果B也很简单,就会先全部运行完B。就不会产生A中有B,交替线程的效果。但是如果使用了sleep()函数以后,就会使得在挂起一段时间以后,A和B,两个线程重新确定CPU运行哪一个。因此就会产生交替运行的结果。代码和结果如下

public class ProductTest {
    public static void main(String[] args) {
        Clerk test =new Clerk();
        Producer p1=new Producer(test);
        Consumer c1=new Consumer(test);
//        Consumer c2=new Consumer(test);
        p1.setName("生产者1");
        c1.setName("消费者1");
//        c2.setName("消费者2");
        p1.start();
        c1.start();
//        c2.start();
    }
}

class Clerk{
    private int producenum=0;
    public synchronized void produce() {
        if(producenum<20){
            producenum++;
            System.out.println(Thread.currentThread().getName()+":生产第"+producenum+"个产品。");
            notify();
        }else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void consume() {
        if(producenum>0){
            System.out.println(Thread.currentThread().getName()+":消费第"+producenum+"个产品。");
            producenum--;
            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer extends Thread{
    private Clerk clerk;
    public Consumer(Clerk test) {
        clerk=test;
    }

    @Override
    public void run() {
        while(true) {
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.consume();
        }
    }
}

class Producer extends Thread{
    private Clerk clerk;
    public Producer(Clerk test) {
        clerk=test;
    }

    @Override
    public void run() {
        while(true) {
            try {
                sleep(1);//虽然只是停止了1ms,但是就会产生正确结果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produce();
        }
    }
}

有sleep()函数

没有sleep函数: 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值