一. 多线程之间如何实现通讯
1.1 什么是多线程之间的通讯
多线程之间通信,其实就是多个线程在操作同一个资源,但是操作的动作不同。
1.2 多线程之间通讯需求
需求:第一个线程写入(input)用户,另一个线程读取(out)用户,实现读一个,写一个操作。
生产者消费者
**涉及到 wait 、 notify **
共享资源源实体类:
class Person{
protected String name;
protected String sex;
protected boolean flag = false;
}
生产线 线程资源
class Product extends Thread{
private Person person;
public Product(Person person){
this.person = person;
}
@Override
public void run() {
int count = 0;
while(true){
synchronized(person) {
// 当 flag 为 flase 时,生产者生产产品,消费者消费产品
// 当 flag 为 true 时,生产者停止生产产品,消费者开始消费产品
if(person.flag){
try {
// wait 的作用是让线程从运行状态变为 休眠状态,类比 sleep
// 但两者还是有差异:wait() 可以释放锁,sleep 不能释放
// wait 和 synchronized 一起在多线程之间实现同步
person.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == 0) {
person.name = "王盼";
person.sex = "女";
} else {
person.name = "王盼盼";
person.sex = "男";
}
count = (count + 1) % 2;
person.flag = true;
// 和 wait() 一起使用,用来唤醒一个线程,将线程聪慧阻塞状态变为与运行状态
person.notify();
}
}
}
}
消费者线程资源
class Custom extends Thread{
private Person person;
public Custom(Person person){
this.person = person;
}
@Override
public void run() {
while(true){
synchronized(person) {
if(!person.flag == true){
try {
person.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(person.name + "----" + person.sex);
person.flag = false;
person.notify();
}
}
}
}
二. 中断一个线程
老板让李四去银行给一个陌生用户转账,李但老板突然来电话了,说转账的对方是个骗子,需要赶紧停止转账,那张三该如何通知李四停止呢?
- 通过共享的标记来进行沟通
实例1
package sin_2020_02_22.sin_2020_02_23;
public class StopThread {
private static class ThreadDemo extends Thread{
private volatile boolean quit = false;
ThreadDemo(){
super("李四");
}
public void setQuit(boolean quit) {
this.quit = quit;
}
@Override
public void run() {
while(!quit){
System.out.println(this.getName()+" 我正在转账不要烦我");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.getName()+" 对面是骗子我不转了");
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new ThreadDemo();
System.out.println("开始转吧");
thread.start();
Thread.sleep(1000 * 10);
System.out.println("对方是骗子,可别转了");
((ThreadDemo) thread).setQuit(true);
System.out.println("给说了");
thread.join();
System.out.println("李四停止转账");
}
}
- 调用 interrupt() 方法来通知(与 interruputed() 配合使用)
实例2
package sin_2020_02_22.sin_2020_02_23;
public class StopThread1 {
private static class ThreadDemo extends Thread{
ThreadDemo(){
super("李四");
}
@Override
public void run() {
while(!this.isInterrupted()){
System.out.println(this.getName()+" 我正在转账不要烦我");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
//e.printStackTrace();
System.out.println("我从睡梦中惊醒");
break;
}
}
System.out.println(this.getName()+" 对面是骗子我不转了");
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new ThreadDemo();
System.out.println("开始转吧");
thread.start();
Thread.sleep(5000);
System.out.println("对方是骗子,可别转了");
thread.interrupt();
System.out.println("给说了");
thread.join();
System.out.println("李四停止转账");
}
}
实例1 | 实例2 |
---|---|
thread.interrupt() | thread.setQuit() |
interrupted() | quit |
this.isInputerrupted() | quit判断 |