线程安全的懒汉式、死锁、ReentrantLock 的使用

  • 解决单例模式中的懒汉式线程安全问题
    • 饿汉式:不存在线程安全问题。
    • 懒汉式:存在线程安全问题,(需要使用同步机制来处理)
  • 死锁
    • 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。我们编写程序时,要避免出现死锁。
    • 诱发死锁的原因:
      • 1.互斥条件
      • 2.占用且等待
      • 3.不可抢夺(或不可抢占)
      • 4.循环等待
  • 如何避免死锁:
    • 1.互斥条件基本上无法被破坏。因为线程需要通过互斥解决安全问题。
    • 2.可以考虑一次性申请所有所需的资源,这样就不存在等待的问题。
    • 3.占用部分资源的线程在进一步申请其他资源时,如果申请不到,就主动释放掉已经占用的资源。
    • 4.可以将使用资源改为线性顺序。申请资源时,先申请序号较小的,这样避免循环等待问题。
  • ReentrantLock 的使用
    • 1.步骤:
      • 1.创建ReentrantLock的实例,需要确保多个线程共用同一个Lock实例!需要考虑将此对象声明为static final
      • 2.执行lock()方法,锁定对共享资源的调用
      • 3.unlock()的调用,释放对共享数据的锁定
      • 代码:
        public class LockTest {
        
        	public static void main(String[] args) {
        		// TODO Auto-generated method stub
        		Ticket t=new Ticket();
        		Thread t1=new Thread(t,"窗口1");
        		Thread t2=new Thread(t,"窗口2");
        		Thread t3=new Thread(t,"窗口3");
        		t1.start();
        		t2.start();
        		t3.start();
        	}
        
        }
        class Ticket implements Runnable{
        	int ticket=100;
        	boolean isFlag=true;
        	static ReentrantLock lock=new ReentrantLock();//创建static的ReentrantLock的实例
        	@Override
        	public void run() {
        		// TODO Auto-generated method stub
        		while(isFlag) {
        			try {
        				Thread.sleep(10);
        			} catch (InterruptedException e) {
        				// TODO Auto-generated catch block
        				e.printStackTrace();
        			}
        			show();
        		}
        	}
        	public void show() {
        		lock.lock();//调用lock()方法
        		if(ticket>0) {
        			System.out.println(Thread.currentThread().getName()+"--->售卖票"+ticket);
        			ticket--;
        		}else {
        			isFlag=false;
        		}
        		lock.unlock();//调用unlock()方法
        	}
        }

    • synchronized同步的方式与Lock的对比
      • synchronized不管是同步代码块还是同步方法,都需要在结束大括号后,释放对同步监视器的调用。Lock是通过两个方法控制需要被同步的代码,更灵活一些。
      • Lock作为接口,提供了多种实现类,适合更多更复杂的场景,效率更高。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值