多线程_并发协作
Posted qust-lgh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程_并发协作相关的知识,希望对你有一定的参考价值。
线程通信
解决方法一:并发协作模型“生产者/消费者模式”->管程法
生产者:负责生产数据的模块(这里的模块可能是:方法、对象、线程、进程);
消费者:负责处理数据的模块(这里的模块可能是:方法、对象、线程、进程);
缓冲区:消费者不能直接使用生产者的数据,它们之间有个“缓冲区”;
生产者将生产好的数据放入“缓冲区”,消费者从“缓冲区”拿要处理的数据。
优点:解耦、提高效率。
public class Cotest01 {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
// 生产者
class Productor extends Thread{
SynContainer container;
public Productor(SynContainer container) {
this.container = container;
}
@Override
public void run() {
// 生产
for (int i = 1; i <= 100; i++) {
System.out.println("生产-->"+i+"馒头");
container.push(new Steamedbun(i));
}
}
}
// 消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
// 消费
for (int i = 1; i <= 100; i++) {
System.out.println("消费-->"+container.pop().id+"馒头");
}
}
}
// 缓冲区
class SynContainer{
Steamedbun[] buns = new Steamedbun[10];// 存储容器
int count = 0;// 计数器
// 存储 生产
public synchronized void push(Steamedbun bun) {
// 何时能生产 容器存在空间
// 不能生产 只能等待 消费者通知生产才解除
if (count == buns.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 存在空间 可以生产
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
buns[count] = bun;
count++;
this.notifyAll();// 存在数据 可以通知消费
}
// 获取 消费
public synchronized Steamedbun pop() {
// 何时消费 容器中是否存在数据
// 没有数据 只有等待
if (count == 0) {
try {
this.wait();// 线程阻塞 生产者通知消费解除阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 存在数据可以消费
count--;
Steamedbun bun = buns[count];
this.notifyAll();// 存在空间了,可以唤醒对方生产了
return bun;
}
}
// 馒头
class Steamedbun{
int id;
public Steamedbun(int id) {
super();
this.id = id;
}
}
解决办法二:并发协作模式“生产者/消费者模式”->信号灯法
public class Cotest02 {
public static void main(String[] args) {
Tv tv= new Tv();
new Player(tv).start();
new Watcher(tv).start();
}
}
// 生产者 演员
class Player extends Thread{
Tv tv;
public Player(Tv tv) {
super();
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i%2==0) {
this.tv.play("奇葩说");
}else {
this.tv.play("太污了,喝瓶立白洗洗嘴");
}
}
}
}
// 消费者 观众
class Watcher extends Thread{
Tv tv;
public Watcher(Tv tv) {
super();
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
// 同一份资源 电视
class Tv{
String voice;
// 信号灯
// T表示演员表演 观众等待
// F表示观众观看 演员等待
boolean flag = true;
// 表演
public synchronized void play(String voice) {
// 演员等待
if (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 表演时刻
this.voice = voice;
System.out.println("表演了:"+voice);
// 唤醒
this.notifyAll();
// 切换标志
this.flag = !this.flag;
}
// 观看
public synchronized void watch() {
// 观众等待
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 观看
System.out.println("听到了:"+voice);
// 唤醒
this.notifyAll();
// 切换标志
this.flag = !this.flag;
}
}
以上是关于多线程_并发协作的主要内容,如果未能解决你的问题,请参考以下文章
Java多线程系列:线程的五大状态,以及线程之间的通信与协作
Java多线程系列:线程的五大状态,以及线程之间的通信与协作