博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java多线程(同步与死锁问题,生产者与消费者问题)
阅读量:6223 次
发布时间:2019-06-21

本文共 3457 字,大约阅读时间需要 11 分钟。

首先我们来看同步与死锁问题:

所谓死锁,就是A拥有banana。B拥有apple。

A对B说:你把apple给我。我就把banana给你。

B对A说:你把banana给我,我就把apple给你。

可是A和B都在等待对方的答复,那么这样终于的结果就是A得不到apple,B也得不到banana。这样的死循环就是死锁。

于是我们能够模拟上面的描写叙述。写出下面代码:

类A代表A这个人,

public class A {	public void say(){		System.out.println("A said to B: if you give me the apple, I will give you the banana.");	}	public void get(){		System.out.println("A get the apple.");	}}

类B代表B这个人,

public class B {	public void say(){		System.out.println("B said to A: if you give me the banana, I will give you the apple.");	}	public void get(){		System.out.println("B get the banana.");	}}

类ThreadDeadLock代表死锁类,

public class ThreadDeadLock implements Runnable{	private static A a=new A();	private static B b=new B();	public boolean flag=false;	public void run(){		if(flag){			synchronized(a){				a.say();				try{					Thread.sleep(500);				}catch(InterruptedException e){					e.printStackTrace();				}				synchronized(b){					a.get();				}			}		}else{			synchronized(b){				b.say();				try{					Thread.sleep(500);				}catch(InterruptedException e){					e.printStackTrace();				}				synchronized(a){					b.get();				}			}		}	}}

以下是主类:

public class Main{	public static void main(String[] args){		ThreadDeadLock t1=new ThreadDeadLock();		ThreadDeadLock t2=new ThreadDeadLock();		t1.flag=true;		t2.flag=false;		Thread thA=new Thread(t1);		Thread thB=new Thread(t2);		thA.start();		thB.start();	}}

程序执行结果:

A said to B: if you give me the apple, I will give you the banana.

B said to A: if you give me the banana, I will give you the apple.

从以上的程序执行。我们能够发现,两个线程都在等待对方的执行完毕。这样,程序也就无法继续执行,从而造成了死锁执行现象。

以下我们来看生产者与消费者问题:

所谓生产者与消费者问题,非常easy,过程就是生产者不断生产产品,消费者不断取走产品。

Producer生产product,Consumer消费product。

于是,我们先定义product类:

public class Product {	private String name="product";	private boolean flag=false;	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public synchronized void set(String name){		if(!flag){			try{				super.wait();			}catch(InterruptedException e){				e.printStackTrace();			}		}		this.setName(name);		try{			Thread.sleep(300);		}catch(InterruptedException e){			e.printStackTrace();		}		flag=false;		super.notify();	}	public synchronized void get(){		if(flag){			try{				super.wait();			}catch(InterruptedException e){				e.printStackTrace();			}		}		try{			Thread.sleep(300);		}catch(InterruptedException e){			e.printStackTrace();		}		System.out.println(this.getName());		flag=true;		super.notify();	}}

这里添加了等待与唤醒。并添加一个标志位flag,flag为true时。表示能够生产。但不能取走,此时假设线程执行到了消费者线程,则应该等待,假设flag为false,则表示能够取走。可是不能生产,假设生产者线程执行,则应该等待。

Producer类:

public class Producer implements Runnable{	private Product product=null;	public Producer(Product product){		this.product=product;	}	public void run(){		for(int i=0;i<50;++i){			this.product.set("product");		}	}}

Consumer类:

public class Consumer implements Runnable{	private Product product=null;	public Consumer(Product product){		this.product=product;	}	public void run(){		for(int i=0;i<50;++i){			try{				Thread.sleep(100);			}catch(InterruptedException e){				e.printStackTrace();			}			this.product.get();		}	}}

然后是主类:

public class Main{	public static void main(String[] args){		Product product=new Product();		Producer pro=new Producer(product);		Consumer con=new Consumer(product);		new Thread(pro).start();		new Thread(con).start();	}}

于是我们知道,生产者每生产一个产品。消费者就取走一个产品,消费者每取走一个产品,就要等待生产者生产。

本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5210993.html,如需转载请自行联系原作者

你可能感兴趣的文章
git workflow 原文 以及缺点
查看>>
QT对话框中show和exec的区别
查看>>
Android和C#实时视频传输Demo
查看>>
java并发编程学习:如何等待多个线程执行完成后再继续后续处理(synchronized、join、FutureTask、CyclicBarrier)...
查看>>
Mysql Binlog三种格式介绍及分析
查看>>
70、二维码生成+圆形头像
查看>>
Pazera Free Audio Extractor 中文版 - 轻松将视频背景音乐/对话音频提取出来的免费软件...
查看>>
读取spring配置文件的方法(spring读取资源文件)
查看>>
PostConstruct
查看>>
MyEclipse------快速读取特定目录下的文件的内容(字节输入流)
查看>>
Linq查询操作之排序操作
查看>>
Spring 4支持的Java 8新特性一览
查看>>
RHEL6.2下挂载光驱安装软件
查看>>
YYCache 源码分析(二)
查看>>
2016年第9本:系统之美
查看>>
framebuff 显示子系统
查看>>
php手册杂记
查看>>
Yii2 定时任务创建(Console 任务)
查看>>
lombok+slf4j+logback SLF4J和Logback日志框架详解
查看>>
PHP 单例模式继承的实现方式
查看>>