zoukankan      html  css  js  c++  java
  • 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.


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


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


    所谓生产者与消费者问题,非常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();
    	}
    }

    所以我们知道。生产者每生产一个产品,删除产品的消费者,删除每个消费者产品。我们必须等待生产者生产。

  • 相关阅读:
    python基础:8.正则表达式
    [Unity工具]批量修改字体
    产品理念(微博和Twitter)
    个性化推荐技术漫谈
    谱聚类算法(转自http://www.cnblogs.com/vivounicorn/archive/2012/02/10/2343377.html)
    Ubuntu输入正确密码后无法登录
    KMeans java实现(未用Hadoop版改进)
    Nutch安装指南
    KMeans的MapReduce实现
    特征向量的几何意义
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4596002.html
Copyright © 2011-2022 走看看