多线程通信问题
比如线程A要去网上下载音乐,B要去网上播放A下载完成后的音乐。这时就要A通知B…进行通信
生产者与消费者
有生产者:厨师
消费者:服务员
厨师做好一份食物(food)后 服务员 上菜,然后服务员把盘子送回到厨师,厨师继续做好食物放入盘子中,让服务员上菜。
public class Communication {
/**
* 多线程通信问题,生产者与消费者问题
* @param args
*/
public static void main(String[] args) {
Food f = new Food();
new Cooker(f).start();
new Waiter(f).start();
}
}
// 厨师
class Cooker extends Thread{
private Food f;
public Cooker(Food f) {
this.f = f;
}
@Override
public void run() {
// 生成food
for (int i = 0; i < 100; i++) {
if (i % 2 == 0){
f.setNameAndTaste("小米粥","甜味");
} else {
f.setNameAndTaste("辣条","辣味");
}
}
}
}
// 服务员
class Waiter extends Thread{
private Food f;
public Waiter(Food f) {
this.f = f;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
f.get();
}
}
}
// 食物盘子
class Food{
private String name;
private String taste;
public void setNameAndTaste(String name, String taste){
this.name = name;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.taste = taste;
}
public void get(){
System.out.println("服务员端走的菜的名称是:" + name + "味道:" + taste);
}
}
结果错误:
加上synchronized:
结果:(更乱)
解决办法:
厨师做菜时,服务员线程睡着,菜做好了,把服务员叫醒,让服务员上菜,这时厨师睡着,等服务员把盘子端回来后,厨师醒来做菜,服务员睡着…这样就不会发生错乱。
public class Communication {
/**
* 多线程通信问题,生产者与消费者问题
* @param args
*/
public static void main(String[] args) {
Food f = new Food();
new Cooker(f).start();
new Waiter(f).start();
}
}
// 厨师
class Cooker extends Thread{
private Food f;
public Cooker(Food f) {
this.f = f;
}
@Override
public void run() {
// 生成food
for (int i = 0; i < 100; i++) {
if (i % 2 == 0){
f.setNameAndTaste("小米粥","甜味");
} else {
f.setNameAndTaste("辣条","辣味");
}
}
}
}
// 服务员
class Waiter extends Thread{
private Food f;
public Waiter(Food f) {
this.f = f;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
f.get();
}
}
}
// 食物盘子
class Food{
private String name;
private String taste;
private boolean flag = true;
public synchronized void setNameAndTaste(String name, String taste){
if (flag){
this.name = name;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.taste = taste;
flag = false;
// 就是唤醒服务员对象
// 唤醒厨师对象让其睡眠的所有对象 --因为这里厨师会调用这个方法
this.notifyAll();
// 厨师睡眠
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void get(){
if (!flag) {
// 厨师做好菜了,服务员来取
System.out.println("服务员端走的菜的名称是:" + name + " 味道:" + taste);
flag = true;
// 唤醒厨师对象
this.notifyAll();
// 服务员睡眠
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果: 没有发生错误