目录
一、volatile 关键字来实现线程间相互通信示例
- 一、volatile 关键字来实现线程间相互通信示例
- 二、Object类的wait()和 notify()方法来实现线程间相互通信示例
- 三、Object类的wait()方法让当前线程进入等待状态,并且释放对象的锁示例
- 四、Object类的notify()方法随机唤醒所有等待线程中的某一线程示例
- 五、Object类的notifyAll方法唤醒所有等待的线程示例
1、代码示例
package com.xz.thread.t13;
/**
* @description: 基于 volatile 关键字来实现线程间相互通信
* 多个线程同时监听一个变量,当这个变量发生变化的时候 ,
* 线程能够感知并执行相应的业务
* @author: xz
* @create: 2021-05-18 22:20
*/
public class Demo1 {
//定义一个共享变量signal来实现通信,它需要是volatile修饰,否则线程不能及时感知
private volatile int signal;//信号
//获取共享变量signal的方法
public int getSignal() {
return signal;
}
//修改共享变量signal的方法
public void setSignal(int signal) {
this.signal = signal;
}
public static void main(String[] args) {
Demo1 demo1=new Demo1();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"修改线程状态开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
demo1.setSignal(1);//设置共享变量signal的值为1
System.out.println(Thread.currentThread().getName()+"修改线程状态结束");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(demo1.getSignal() !=1){//signal!=1,什么都不执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//当signal==1的时候开始执行
System.out.println(Thread.currentThread().getName()+"执行代码。。。。");
}
}).start();
}
}
2、运行main函数,输出截图如下:
- 注:wait()和 notify()方法必须放在同步代码块或者同步方法中使用
1、代码示例
package com.xz.thread.t13;
/**
* @description: Object类的wait()和 notify()方法来实现线程间相互通信
* wait()和 notify()方法必须放在同步代码块或者同步方法中使用
* @author: xz
* @create: 2021-05-18 22:30
*/
public class Demo2 {
//定义一个共享变量signal来实现通信,它需要是volatile修饰,否则线程不能及时感知
private volatile int signal;//信号
//获取共享变量signal的方法
public int getSignal() {
return signal;
}
//修改共享变量signal的方法
public void setSignal(int signal) {
this.signal = signal;
}
public static void main(String[] args) {
Demo2 demo2=new Demo2();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (demo2){
System.out.println(Thread.currentThread().getName()+"修改线程状态开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
demo2.setSignal(1);
System.out.println(Thread.currentThread().getName()+"修改线程状态结束");
demo2.notify();//notify()方法必须放在同步代码块或者同步方法中使用
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (demo2){
while(demo2.getSignal() !=1){//signal!=1,所以什么都不执行
try {
demo2.wait();//wait()必须放在同步代码块或者同步方法中使用
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//当signal==1的时候开始执行
System.out.println(Thread.currentThread().getName()+"执行代码。。。。");
}
}
}).start();
}
}
2、运行main函数,输出截图如下:
1、代码示例
package com.xz.thread.t13;
public class Demo3 {
//定义一个共享变量signal来实现通信,它需要是volatile修饰,否则线程不能及时感知
private volatile int signal;//信号
//定义一个执行代码的get方法
public synchronized int get() {
System.out.println(Thread.currentThread().getName()+"代码执行开始");
if(signal != 1){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"代码执行结束");
return signal;
}
public static void main(String[] args) {
Demo3 demo3 = new Demo3();
//创建线程任务
Target2 target2 = new Target2(demo3);
//开始创建线程
new Thread(target2).start();
new Thread(target2).start();
new Thread(target2).start();
new Thread(target2).start();
}
}
package com.xz.thread.t13;
public class Target2 implements Runnable{
private Demo3 demo3;
public Target2(Demo3 demo){
this.demo3 =demo;
}
//执行代码
@Override
public void run() {
demo3.get();
}
}
2、运行main函数,输出截图如下: 3、结论
- Object类的wait()方法让当前线程进入等待状态,并且释放对象的锁,所以其他线程才进入了synchronized关键字修饰的get()方法。
1、代码示例
package com.xz.thread.t13;
/**
* @author: xz
* @create: 2021-05-18 22:51
*/
public class Demo3 {
//定义一个共享变量signal来实现通信,它需要是volatile修饰,否则线程不能及时感知
private volatile int signal;//信号
//定义一个修改线程状态的set方法
public synchronized void set() {
signal=1;
notify();//调用notify()方法,随机唤醒所有等待线程中的某一线程
}
//定义一个执行代码的get方法
public synchronized int get() {
System.out.println(Thread.currentThread().getName()+"代码执行开始");
if(signal != 1){
try {
wait();//调用wait()方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"代码执行结束");
return signal;
}
public static void main(String[] args) {
Demo3 demo3 = new Demo3();
//分别创建两个线程任务
Target1 target1 = new Target1(demo3);
Target2 target2 = new Target2(demo3);
//开始4个线程,target2中调用get方法中的wait()
new Thread(target2).start();
new Thread(target2).start();
new Thread(target2).start();
new Thread(target2).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//开始1个线程,target1中调用set方法中的notify()
new Thread(target1).start();
}
}
package com.xz.thread.t13;
/**
* @description:
* @author: xz
* @create: 2021-05-18 23:00
*/
public class Target1 implements Runnable{
private Demo3 demo3;
public Target1(Demo3 demo){
this.demo3 =demo;
}
//修改线程状态
@Override
public void run() {
demo3.set();
}
}
package com.xz.thread.t13;
/**
* @description:
* @author: xz
* @create: 2021-05-18 23:01
*/
public class Target2 implements Runnable{
private Demo3 demo3;
public Target2(Demo3 demo){
this.demo3 =demo;
}
//执行代码
@Override
public void run() {
demo3.get();
}
}
2、运行main函数,输出截图如下:
3、结论
- 由第2步骤的输出结果截图可知,Object类的notify()方法随机唤醒所有等待线程中的某一线程;
- 第一张截图唤醒了Thread-2;第二张截图唤醒了Thread-0;
1、代码示例
package com.xz.thread.t13;
/**
* @author: xz
* @create: 2021-05-18 22:51
*/
public class Demo3 {
//定义一个共享变量signal来实现通信,它需要是volatile修饰,否则线程不能及时感知
private volatile int signal;//信号
//定义一个修改线程状态的set方法
public synchronized void set() {
signal=1;
notifyAll();//调用notifyAll()方法,唤醒所有等待的线程
}
//定义一个执行代码的get方法
public synchronized int get() {
System.out.println(Thread.currentThread().getName()+"代码执行开始");
if(signal != 1){
try {
wait();//调用wait()方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"代码执行结束");
return signal;
}
public static void main(String[] args) {
Demo3 demo3 = new Demo3();
//分别创建两个线程任务
Target1 target1 = new Target1(demo3);
Target2 target2 = new Target2(demo3);
//开始4个线程,target2中调用get方法中的wait()
new Thread(target2).start();
new Thread(target2).start();
new Thread(target2).start();
new Thread(target2).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//开始1个线程,target1中调用set方法中的notifyAll()
new Thread(target1).start();
}
}
package com.xz.thread.t13;
/**
* @description:
* @author: xz
* @create: 2021-05-18 23:00
*/
public class Target1 implements Runnable{
private Demo3 demo3;
public Target1(Demo3 demo){
this.demo3 =demo;
}
//修改线程状态
@Override
public void run() {
demo3.set();
}
}
package com.xz.thread.t13;
/**
* @description:
* @author: xz
* @create: 2021-05-18 23:01
*/
public class Target2 implements Runnable{
private Demo3 demo3;
public Target2(Demo3 demo){
this.demo3 =demo;
}
//执行代码
@Override
public void run() {
demo3.get();
}
}
2、运行main函数,输出截图如下:
3、结论
- 由第2步骤的输出结果截图可知,Object类的notifyAll()方法唤醒所有等待的线程,争夺到时间片的线程只有一个;