设为首页 加入收藏

TOP

Java多线程(同步与死锁问题,生产者与消费者问题)(一)
2015-04-07 15:28:58 来源: 作者: 【 】 浏览:57
Tags:Java 线程 同步 问题 生产者 消费者

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


所谓死锁,就是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.


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


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


所谓生产者与消费者问题,很简单,过程就是生产者不断生产产品,消费者不断取走产品。


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();
?}
}


于是我们知道,生产者每生产一个产

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Java序列化与static 下一篇编译安装 GCC 4.9并验证使用

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: