1. 程式人生 > >多線程_並發協作

多線程_並發協作

ack 切換 對象 main print 並發 count cat all

線程通信

解決方法一:並發協作模型“生產者/消費者模式”->管程法

生產者:負責生產數據的模塊(這裏的模塊可能是:方法、對象、線程、進程);

消費者:負責處理數據的模塊(這裏的模塊可能是:方法、對象、線程、進程);

緩沖區:消費者不能直接使用生產者的數據,它們之間有個“緩沖區”;

生產者將生產好的數據放入“緩沖區”,消費者從“緩沖區”拿要處理的數據。

優點:解耦、提高效率。

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;
}
}

多線程_並發協作