欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java多线程:sleep和wait区别及使用场景

程序员文章站 2022-07-10 18:48:16
1. 区别&使用场景方法CPU锁所属类作用使用场景sleep()释放持有Thread用于Thread内部时序控制延迟几秒执行wait()释放释放Object与notify成对,用于线程协助生产者&消费者模式yield()释放释放Object初衷是为了提高线程之间的相对进度,防止过度使用CP...

1. 区别&使用场景

方法 CPU 所属类 作用 使用场景
sleep() 释放

持有

Thread 用于Thread内部时序控制 延迟几秒执行
wait() 释放

释放

Object 与notify成对,用于线程协助 生产者&消费者模式
yield() 释放 释放 Object 初衷是为了提高线程之间的相对进度,防止过度使用CPU的 实际应用中用到较少,平时多用于调试
join() - - Thread 使当前线程停下来等待,直至调用join方法的线程终止,当前线程继续执行; 当需要等待多个线程执行结果时可以适当使用;也可借助ExecutorService中的submit

2. 生产者模式

wait()/notify() 实现简单的生产者模式如下,实际项目中建议大家借助阻塞队列(BlockingQueue)辅助实现,代码更为简洁、清晰

class Producer implements Runnable {

    private Queue<Integer> mQueue;

    private static final int MAX_SIZE = 3;
    private Random mRandom = new Random();
    private static int count = 0;
    private static int id = 1;
    private String mTag;

    public Producer(Queue<Integer> queue) {
        this.mQueue = queue;
        mTag = String.format("%s#%d:", Producer.class.getSimpleName(), id++);
    }

    @Override
    public void run() {
        while (true) {
            synchronized (mQueue) {
                while (mQueue.size() == MAX_SIZE) {
                    try {
                        System.out.println(mTag + "Queue is full ! Start waiting");
                        mQueue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(mTag + "produce one element value = " + count);
                mQueue.offer(count++);
                mQueue.notifyAll();
                try {
                    Thread.sleep(mRandom.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Consumer implements Runnable {

    private Queue<Integer> mQueue;
    private Random mRandom = new Random();
    private static int id = 1;
    private String mTag;

    public Consumer(Queue<Integer> queue) {
        this.mQueue = queue;
        mTag = String.format("%s#%d:", Consumer.class.getSimpleName(), id++);
    }

    @Override
    public void run() {
        while (true) {
            synchronized (mQueue) {

                while (mQueue.isEmpty()) {
                    System.out.println(mTag + "Queue is empty ! Start waiting");
                    try {
                        mQueue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                int element = mQueue.poll();
                System.out.println(mTag + "Consume one element value = " + element);
                mQueue.notifyAll();

                try {
                    Thread.sleep(mRandom.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

本文地址:https://blog.csdn.net/laofeifd/article/details/108250023