2023-08-28 16:20

synchronized、ReentrantLock实现多线程同步

码自答

JavaEE

(433)

(0)

收藏

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条评论

点击登录参与评论