Java多线程详解(三)

   1)死锁

    两个线程相互等待对方释放同步监视器时会出现死锁的现象,这时所有的线程都处于阻塞状态,程序无法继续向下执行。

   如下就是会出现死锁的程序。

首先flag = 1,线程d1开始执行,锁住对象o1,sleep0.5s,同时线程2开始执行,flag = 0;锁住对象o2;sleep1.5s,执行线程切换到d1,此时要锁住对象o2,但是o2正在被线程d2锁住,线程切换到d2,d2要锁住o1,但是o1正在被d1对象锁住。出现了两个线程相互等待对方释放锁。都处于阻塞状态,程序等待,无法继续执行。

/*
*@author wxismeit@163.com
*/


 

public class DeadLock implements Runnable{
	
	public int flag;
	static Object o1 = new Object();
	static Object o2 = new Object();
	
    public void run() {
    	System.out.println("flag = " + flag);
    	if(flag == 1) {
    		synchronized(o1) {
    			try {
    				Thread.sleep(500);
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		
    		   synchronized(o2) {
    			  System.out.println(1);
    		   }
    		}
    		
    	}
    	if(flag == 0) {
    		synchronized(o2) {
    			try {
    				Thread.sleep(500);
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		
    		   synchronized(o1) {
    			   System.out.println(0);
    		   }
    		}
    	}
	}
	public static void main(String[] args) {
		DeadLock d1 = new DeadLock();
		DeadLock d2 = new DeadLock();
		d1.flag = 1;
		d2.flag = 0;
		Thread t1 = new Thread(d1);
		Thread t2 = new Thread(d2);
		t1.start();
		t2.start();
	}
}

 

2)线程同步模拟生产者与消费者问题。

首先明确wait方法与sleep方法的区别 :wait方法是Object类的方法,导致当前线程等待。知道有其他的线程调用notify或者notifyAll方法唤醒这个线程。但是wait方法会先释放锁,然后让其他线程执行,而sleep方法则不同。wait方法必须是用synchronized修饰的同步方法或者对象才可以调用。

 

用模拟线程安全的栈的方法来做产品的容器。生产者消费者各为一个模拟线程。利用线程同步来处理生产与消费的关系。

代码如下 :

public class Producer implements Runnable {
	private Storage storage;
    public Producer(Storage s) {
    	storage = s;
    }
	public void run() {
		Product p = new Product("DELL", "computer");
		storage.Push(p);
	}

}
public class Consumer implements Runnable{
	private Storage storage;
	
	public Consumer(Storage s) {
		storage = s;
	}

	public void run() {
		storage.Pop();
	}
	

}


 

public class Product {
	private String Id;
	private String name;
	
	public Product(String Id, String name) {
		this.Id = Id;
		this.name = name;
	}
	
	public String getId() {
		return Id;
	}
	public void setId(String Id) {
		this.Id = Id;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		
		return "Id : " + Id + "  name : " + name;
	}

	
}


 

import java.util.Stack;


public class Storage {
	private Product[] product = new Product[10];
	private int top = 0;//
	
	public synchronized void Push(Product p) {
		if(top == product.length) {
			try {
				wait();
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
		product[top++] = p;
		System.out.println(Thread.currentThread().getName() + " 生产了 :" + p);
		notifyAll();
	}
	public synchronized Product Pop() {
		if(top == 0) {
			try {
				wait();
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
	    --top;
	    Product pp = new Product(product[top].getId(), product[top].getName());
		product[top] = null;
		System.out.println(Thread.currentThread().getName() + "消费了 :" + pp);
		notifyAll();
		return pp;
	}
	
	

}

<pre class="java" name="code">public class ProducerAndConsumer {

	public static void main(String[] args) {
		Storage s = new Storage();
		Thread consumer = new Thread(new Consumer(s));
		Thread producer = new Thread(new Producer(s));
        consumer.setName("消费者");
        producer.setName("生产者");
        consumer.start();
        producer.start();
	}

}

//完美运行

 

评论区留下邮箱可获得《Java所线程设计模式》

转载请指明来源

posted @ 2014-12-11 12:59  Pickle  阅读(228)  评论(0编辑  收藏  举报