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