【Java多线程】wait(),sleep(),notify()和notifyAll()方法详解

  sleep()是线程类(Thread)的方法,导致此线程暂停执行指定的时间,到时后会自动恢复,调用sleep()不会释放对象锁。 sleep()方法是正在执行的线程主动让出CPU。wait()Object类的方法,对此对象调用wait()方法导致本线程放弃对象锁,进入对象的等待锁定池,只有当此对象调用notify()方法(或notifyAll())后,本线程才进入对象锁定池准备获得对象锁进入运行状态。notifyAll()Object类的方法,其作用是唤醒在此对象监视器上等待的所有线程。具体可参考以下代码:

public class MultiThread {
    public static void main(String[] args) {
        new Thread(new SubThread1()).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new SubThread2()).start();
    }

    private static class SubThread1 implements Runnable {
        public void run() {
            synchronized (MultiThread.class) {
                System.out.println("Enter SubThread1>>>>>>>>>>>>>>>>>>>>>>");
                System.out.println("SubThread1 is waiting>>>>>>>>>>>>>>>>>");
                try {
                    //wait()会释放锁,本线程会进入等待锁定池
                    /*此时运行结果:
                    Enter SubThread1>>>>>>>>>>>>>>>>>>>>>>
                    SubThread1 is waiting>>>>>>>>>>>>>>>>>
                    Enter SubThread2>>>>>>>>>>>>>>>>>>>>>>
                    SubThread2 notify other thread can release wait status..
                    SubThread2 is sleeping ten millisecond...
                    SubThread2 is going on.
                    SubThread1 is going on.*/
//                    MultiThread.class.wait();

                    //sleep()不会释放锁
                    /*此时运行结果:
                    Enter SubThread1>>>>>>>>>>>>>>>>>>>>>>
                    SubThread1 is waiting>>>>>>>>>>>>>>>>>
                    SubThread1 is going on.
                    Enter SubThread2>>>>>>>>>>>>>>>>>>>>>>
                    SubThread2 notify other thread can release wait status..
                    SubThread2 is sleeping ten millisecond...
                    SubThread2 is going on.*/
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("SubThread1 is going on.");
            }
        }
    }

    private static class SubThread2 implements Runnable {
        public void run() {
            synchronized (MultiThread.class) {
                System.out.println("Enter SubThread2>>>>>>>>>>>>>>>>>>>>>>");
                System.out.println("SubThread2 notify other thread can release wait status..");
                //notify()不会释放锁,当本同步代码块执行结束,别的线程才有可能执行
                MultiThread.class.notify();
                System.out.println("SubThread2 is sleeping ten millisecond...");
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("SubThread2 is going on.");
            }
        }
    }
}

引申

  利用wait()notify()实现生产者消费者模型
  生产者代码:

import java.util.Queue;
import java.util.Random;

/**
 * @author Katakuly
 * @date 2019/7/11
 */
public class Producer implements Runnable {
    private Queue<Integer> queue;
    private int maxSize;

    public Producer(Queue<Integer> queue, int maxSize) {
        this.queue = queue;
        this.maxSize = maxSize;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            synchronized (queue) {
                while (queue.size() == maxSize) {
                    try {
                        System.out.println("Queue is Full");
                        queue.wait();
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
                Random random = new Random();
                int j = random.nextInt();
                System.out.println("Produce " + j);
                queue.add(j);
                queue.notifyAll();
            }
        }
    }
}

消费者代码:

import java.util.Queue;

/**
 * @author Katakuly
 * @date 2019/7/11
 */
public class Consumer implements Runnable {

    private Queue<Integer> queue;
    private int maxSize;

    public Consumer(Queue<Integer> queue, int maxSize) {
        this.queue = queue;
        this.maxSize = maxSize;
    }

    @Override
    public void run() {
        for (int i = 0; i < 6; i++) {
            synchronized (queue) {
                while (queue.isEmpty()) {
                    System.out.println("Queue is Empty");
                    try {
                        queue.wait();
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
                int v = queue.remove();
                System.out.println("Consume " + v);
                queue.notifyAll();
            }
        }
    }
}


主程序:

import java.util.LinkedList;
import java.util.Queue;

/**
 * @author Katakuly
 * @date 2019/7/11
 */
public class Solution {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        int maxSize = 10;
        Producer producer = new Producer(queue, maxSize);
        Consumer consumer = new Consumer(queue, maxSize);
        Thread producerThread = new Thread(producer);
        Thread consumerThread = new Thread(consumer);
        producerThread.start();
        consumerThread.start();
    }
}

  本例设定生产者生产了三个对象,而消费者需要消费六个对象,所以在三个对象消费完之后,剩下的消费者消费对象只能是空,如果想不断的生产消费,可将for()循环修改成while(true)。如下是运行结果:

Produce 1745693584
Produce 894010005
Produce 2090675163
Consume 1745693584
Consume 894010005
Consume 2090675163
Queue is Empty
发布了28 篇原创文章 · 获赞 12 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Carson_Chu/article/details/95505473