博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程详解(三)
阅读量:5948 次
发布时间:2019-06-19

本文共 3263 字,大约阅读时间需要 10 分钟。

   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;	}		}
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所线程设计模式》

转载请指明来源

你可能感兴趣的文章
Mycat源码中的单例模式
查看>>
WPF Dispatcher介绍
查看>>
fiddler展示serverIP方法
查看>>
已释放的栈内存
查看>>
Android网络之数据解析----SAX方式解析XML数据
查看>>
Java递归列出所有文件和文件夹
查看>>
[关于SQL]查询成绩都大于80分的学生
查看>>
Delphi(Tuxedo,BDE,ADO)三合一数据集组件HsTxQuery
查看>>
LeetCode - Longest Common Prefix
查看>>
Android图片处理
查看>>
2015年第21本:万万没想到,用理工科思维理解世界
查看>>
大家谈谈公司里的项目经理角色及职责都是干什么的?
查看>>
剑指offer
查看>>
Velocity魔法堂系列二:VTL语法详解
查看>>
NopCommerce架构分析之八------多语言
查看>>
转:Eclipse自动补全功能轻松设置
查看>>
mysql update操作
查看>>
Robots.txt - 禁止爬虫(转)
查看>>
MySQL数据库
查看>>
Mysql 监视工具
查看>>