且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

java多线程(同步与死锁问题,生产者与消费者问题)

更新时间:2021-09-11 04:49:28

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


所谓死锁,就是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,如需转载请自行联系原作者