java多线程之synchronized与lock、wait与notify详解编程语言

一、synchronized与lock


synchronized在java很早的版本就已经有了,它的作用只要是同步代码,解决线程的安全问题,但是随着java的发展,以及开发业务的不断提高,synchronized的功能渐渐的有些不能够满足复杂业务的需求了。于是在jdk1.5并发包中出现了lock(锁)。lock和synchronized最大的区别在于synchronized是自己开锁,代码走完后自己解锁;而lock则需要手动开锁、解锁,自由度更加高了,满足于更加复杂的业务逻辑。

二、wait与notify

在synchronized里一般和wait与notify一起使用。wait的作用是使当前线程阻塞,和sleep类似,都是让线程睡眠。但是wait是可以手动唤醒线程的,而sleep则只能等待线程苏醒。notify的作用则是唤醒当前线程,让线程从阻塞状态变为运行状态。

三、代码实例

1.synchronized

class Res { 
	public String name; 
	public String sex; 
	public Boolean flag = false; 
} 
 
class InputThread extends Thread { 
 
	private Res res; 
 
	public InputThread(Res res) { 
		this.res = res; 
	} 
 
	@Override 
	public void run() { 
		int count = 0; 
		while (true) { 
			synchronized (res) { 
				if(res.flag){ 
					try { 
						//使线程阻塞 
						res.wait(); 
					} catch (InterruptedException e) { 
						e.printStackTrace(); 
					} 
				} 
				if (count == 0) { 
					res.name = "小明"; 
					res.sex = "男"; 
				}else{ 
					res.name = "小红"; 
					res.sex = "女"; 
				} 
				count = (count+1)%2; 
				//将flag设置为 true 说明已经写完了 
				res.flag = true; 
				//唤醒线程 
				res.notify(); 
			} 
		} 
	} 
} 
 
class OutThread extends Thread { 
 
	private Res res; 
 
	public OutThread(Res res) { 
		this.res = res; 
	} 
 
	@Override 
	public void run() { 
		while (true) { 
			synchronized (res) { 
				if(!res.flag){ 
					try { 
						//使线程阻塞 
						res.wait(); 
					} catch (InterruptedException e) { 
						e.printStackTrace(); 
					} 
				} 
				System.out.println(res.name+"---"+res.sex); 
				//将状态改为false 说明已经读完了 
				res.flag = false; 
				//唤醒线程 
				res.notify(); 
			} 
		} 
	} 
} 
 
public class ThreadDemo05 { 
 
	public static void main(String[] args) { 
		Res res = new Res(); 
		InputThread inputThread = new InputThread(res); 
		OutThread outThread = new OutThread(res); 
		inputThread.start(); 
		outThread.start(); 
	} 
 
}

结果:实现了生产者与消费者模式,一个线程写、一个线程读

java多线程之synchronized与lock、wait与notify详解编程语言

小明---男 
小红---女 
小明---男 
小红---女 
小明---男 
小红---女 
小明---男

2.lock

class Res { 
	public String name; 
	public String sex; 
	public Boolean flag = false; 
	public Lock lock = new ReentrantLock(); 
	Condition condition = lock.newCondition(); 
} 
 
class InputThread extends Thread { 
 
	private Res res; 
 
	public InputThread(Res res) { 
		this.res = res; 
	} 
 
	@Override 
	public void run() { 
		int count = 0; 
		while (true) { 
			try { 
				// 开锁 
				res.lock.lock(); 
				if (res.flag) { 
					try { 
						// 使线程阻塞阻塞 
						res.condition.await(); 
					} catch (InterruptedException e) { 
						// TODO Auto-generated catch block 
						e.printStackTrace(); 
					} 
				} 
				if (count == 0) { 
					res.name = "小明"; 
					res.sex = "男"; 
				} else { 
					res.name = "小红"; 
					res.sex = "女"; 
				} 
				count = (count + 1) % 2; 
				// 将flag设置为 true 说明已经写完了 
				res.flag = true; 
			 
			} catch (Exception e) { 
				// TODO: handle exception 
			} finally { 
				// 唤醒线程 
				res.condition.signal(); 
				// 解锁 
				res.lock.unlock(); 
			} 
		} 
	} 
} 
 
class OutThread extends Thread { 
 
	private Res res; 
 
	public OutThread(Res res) { 
		this.res = res; 
	} 
 
	@Override 
	public void run() { 
		while (true) { 
			try { 
				res.lock.lock(); 
				if (!res.flag) { 
					try { 
						// 使线程阻塞阻塞 
						res.condition.await(); 
					} catch (InterruptedException e) { 
						e.printStackTrace(); 
					} 
				} 
				System.out.println(res.name + "---" + res.sex); 
				// 将状态改为false 说明已经读完了 
				res.flag = false; 
			} catch (Exception e) { 
				// TODO: handle exception 
			} finally { 
				// 唤醒线程 
				res.condition.signal(); 
				//解锁 
				res.lock.unlock(); 
			} 
		} 
	} 
} 
 
public class ThreadDemoLock { 
 
	public static void main(String[] args) { 
		Res res = new Res(); 
		InputThread inputThread = new InputThread(res); 
		OutThread outThread = new OutThread(res); 
		inputThread.start(); 
		outThread.start(); 
	} 
 
}


与lock配套使用的还有condition,jdk1.8中描述,Condition因素的 Object监测方法( wait, notify和 notifyAll)为不同的对象给在每个对象的多个等待集的影响,结合 Lock实现任意使用。在 Lock取代 synchronized方法和语句的使用,一个 Condition取代对象监视器的使用方法。

实际上实现了阻塞和唤醒线程的功能

java多线程之synchronized与lock、wait与notify详解编程语言

小明---男 
小红---女 
小明---男 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/16129.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论