Java运行多线程并发运行,如果多个线程执行过程中需要访问同一个资源,可能会导致资源数据不正确。
例如:有150张火车票,多个窗口同时售卖,就可能出现不同窗口卖出同一张票。
package com.wanmait.sys;
public class TrainTickets implements Runnable
{
	private int count = 150;
	
	public void run()
	{
		while(true)
		{
			if(count>0)//还有余票
			{
				System.out.println("窗口卖"+count+"号票");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
				count--;
			}
		}
	}
}线程同步,在一个线程访问资源没有结束之前,其他线程不能访问。
线程同步实现:
- 方式一 - synchronized实现 - 任意一个对象,都有自己独立的监视器(monitor),当执行同步代码时,必须先获得该对象的监视器,然后才能执行同步代码,没有获得监视器的线程,只能等待,成为阻塞状态,等到获得监视器的线程执行完毕。 
- public class TrainTickets implements Runnable { private int count = 150; public void run() { while(true) { if(count>0)//还有余票 { synchronized(this) { System.out.println("窗口卖"+count+"号票"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } count--; } } } } }
- 方式二 
ReentrantLock
锁对象,通过ReentrantLock对象获取和释放锁
lock()锁对象 unlock()方法解锁
import java.util.concurrent.locks.ReentrantLock;
public class TrainTickets implements Runnable
{
	private int count = 150;
	private ReentrantLock lock = new ReentrantLock();
	
	public void run()
	{
		while(true)
		{
			if(count>0)//还有余票
			{	
				lock.lock();
				
				System.out.println("窗口卖"+count+"号票");
				
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				count--;
				
				lock.unlock();
			}
		}
	}
}区别:
1 ReentrantLock是类 synchronized是关键字
2 synchronized发生异常时,自动释放线程占有的锁,ReentrantLock出现异常,不会释放锁,所以需要在finally调用unlock方法释放锁
3 synchronized是非公平锁,ReentrantLock可以设置成为公平锁,让所有的线程都有执行的机会
4 synchronized是不可中断锁,ReentrantLock是可中断锁
 
 
 
					
						
									
					 
					
						
									
					 
					
						
									
					 
						
									
					 
						
									
					 
						
									
					 
						
									
					 
						
									
					
0条评论
点击登录参与评论