线程通信涉及到的三个方法: (1)wait():一旦执行此方法当前线程进入阻塞状态,并释放同步监视器 (2)notify():一旦执行此方法就会唤醒被wait的另一个线程。如果存在多个被wait的线程,唤醒优先级高的线程。 (3)notifyAll():一旦执行此方法就会唤醒所有被wait的线程 说明: (1)wait()、notify()、notifyAll()三个方法必须在同步代码块或同步方法里面使用 (2)wait()、notify()、notifyAll()三个方法的调用者必须是同步代码块或同步方法里面的同步监视器 如下面的,obj对象作为同步监视器的话其他地方调用这个三个方法也需要使用obj对象 (3)因为任何一个对于多线程来说是唯一的对象都可以充当同步监视器,所以上面三个方法是定义在Object对象里面的。 面试题:sleep()和wait()方法的异同 相同:一旦执行上面两种方法就会使当前线程进入阻塞状态 不同: (1)两个方法声明的位置不同,sleep()方法声明在Thread类里面,wait()方法声明在Object类里面 (2)调用要求不同,sleep()方法可以在任何需要的场景下面使用,wait()方法必须在同步代码块或同步方法里面使用 (3)关于释放同步监视器的问题:如果sleep()和wait()方法都在步代码块或同步方法里面使用时, sleep()方法不会释放同步监视器,而wait()方法会释放同步监视器
package com.jinjian;
/**
线程通信的例子:两个线程依次打印1到100
线程通信涉及到的三个方法:
(1)wait():一旦执行此方法当前线程进入阻塞状态,并释放同步监视器
(2)notify():一旦执行此方法就会唤醒被wait的另一个线程。如果存在多个被wait的线程,唤醒优先级高的线程。
(3)notifyAll():一旦执行此方法就会唤醒所有被wait的线程
说明:
(1)wait()、notify()、notifyAll()三个方法必须在同步代码块或同步方法里面使用
(2)wait()、notify()、notifyAll()三个方法的调用者必须是同步代码块或同步方法里面的同步监视器
如下面的,obj对象作为同步监视器的话其他地方调用这个三个方法也需要使用obj对象
(3)因为任何一个对于多线程来说是唯一的对象都可以充当同步监视器,所以上面三个方法是定义在Object对象里面的。
面试题:sleep()和wait()方法的异同
相同:一旦执行上面两种方法就会使当前线程进入阻塞状态
不同:
(1)两个方法声明的位置不同,sleep()方法声明在Thread类里面,wait()方法声明在Object类里面
(2)调用要求不同,sleep()方法可以在任何需要的场景下面使用,wait()方法必须在同步代码块或同步方法里面使用
(3)关于释放同步监视器的问题:如果sleep()和wait()方法都在步代码块或同步方法里面使用时,
sleep()方法不会释放同步监视器,而wait()方法会释放同步监视器
*/
class Num implements Runnable{
private Object object = new Object();
private int num = 0;
@Override
public void run() {
while (true){
//synchronized (object){
synchronized (this){
//this. notify();
//obj. notify();
notify();
if(num < 100){
System.out.println(Thread.currentThread().getName() + " prinf " + num);
num++;
try {
//使得调用wait()的线程进入阻塞状态,且会释放本身的锁
//this.wait();
//obj.wait();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}
}
}
}
}
public class ThreadCommunication {
public static void main(String[] args) {
Num num = new Num();
Thread t1 = new Thread(num);
Thread t2 = new Thread(num);
t1.start();
t2.start();
}
}
生产者消费者例题
package com.jinjian;
/**
消费者和生产者例题,生产者生产物品超过20个就会停一下,消费者消费
*/
class Client{
private int num = 0;
public synchronized void product() {
if(num < 20){
num++;
System.out.println(Thread.currentThread().getName() + " 生产了第 " + num + "个产品");
notify();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void consume(){
if(num > 0){
System.out.println(Thread.currentThread().getName() + " 消费者消费了第" + num + "个产品");
num--;
notify();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread{
private Client client;
public Producer(Client client){
this.client = client;
}
@Override
public void run() {
System.out.println(getName()+" 生产者开始生产.......");
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
client.product();
}
}
}
class Consumer extends Thread{
private Client client;
public Consumer(Client client){
this.client = client;
}
@Override
public void run() {
System.out.println(getName()+" 消费者开始消费.......");
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
client.consume();
}
}
}
public class ProducerAndConsumer {
public static void main(String[] args) {
Client client = new Client();
Producer producer = new Producer(client);
Consumer consumer = new Consumer(client);
producer.setName("peoducer1");
consumer.setName("consumer1");
producer.start();
consumer.start();
}
}