zoukankan      html  css  js  c++  java
  • 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所线程设计模式》

    转载请指明来源

  • 相关阅读:
    网页源码爬取
    Vue模板语法上集
    SSH整合
    P1290 欧几里德的游戏
    P1582 倒水
    P2158 [SDOI2008]仪仗队
    P1338 末日的传说
    P1372 又是毕业季I
    P1865 A % B Problem
    P1031 均分纸牌
  • 原文地址:https://www.cnblogs.com/wxisme/p/4363754.html
Copyright © 2011-2022 走看看