- 解决单例模式中的懒汉式线程安全问题
- 饿汉式:不存在线程安全问题。
- 懒汉式:存在线程安全问题,(需要使用同步机制来处理)
- 死锁
- 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。我们编写程序时,要避免出现死锁。
- 诱发死锁的原因:
- 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作为接口,提供了多种实现类,适合更多更复杂的场景,效率更高。
- 1.步骤:
线程安全的懒汉式、死锁、ReentrantLock 的使用
最新推荐文章于 2024-03-03 23:05:46 发布