代码:
package Test0629;public class BankTest {static Bank b1 = null;static Bank b2 = null;public static void main(String[] args) {Thread t1 = new Thread(){public void run(){b1 = Bank.getInstance();}};Thread t2 = new Thread(){public void run(){b2 = Bank.getInstance();}};t1.start();t2.start();try {t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}try {t2.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(b1);System.out.println(b2);System.out.println(b1 == b2);}
}
class Bank{private Bank(){}private static Bank instance = null;public static Bank getInstance() {if(instance == null){try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}instance = new Bank();}return instance;}
}
方式一:
package Test0629;public class BankTest {static Bank b1 = null;static Bank b2 = null;public static void main(String[] args) {Thread t1 = new Thread(){public void run(){b1 = Bank.getInstance();}};Thread t2 = new Thread(){public void run(){b2 = Bank.getInstance();}};t1.start();t2.start();try {t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}try {t2.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(b1);System.out.println(b2);System.out.println(b1 == b2);}}class Bank{private Bank(){}private static Bank instance = null;public static Bank getInstance() { //同步监视器,默认为Bank.classif(instance == null){synchronized(Bank.class){if(instance == null){try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}instance = new Bank();}}}return instance;}}
方式二:
package Test0629;public class BankTest {static Bank b1 = null;static Bank b2 = null;public static void main(String[] args) {Thread t1 = new Thread(){public void run(){b1 = Bank.getInstance();}};Thread t2 = new Thread(){public void run(){b2 = Bank.getInstance();}};t1.start();t2.start();try {t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}try {t2.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(b1);System.out.println(b2);System.out.println(b1 == b2);}}class Bank{private Bank(){}private static Bank instance = null;public static synchronized Bank getInstance() { //同步监视器,默认为Bank.classif(instance == null){if(instance == null){try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}instance = new Bank();}}return instance;}}
线程的同步机制带来的问题:死锁
1如何看待死锁?
2。诱发死锁的原因?
诱发死锁的原因
。互斥条件
。占用且等待
。不可抢夺 (或不可抢占)
。循环等待
以上4个条件,同时出现就会触发死锁。
3,如何避免死锁?
解决死锁:死锁一旦出现,基本很难人为干预,只能尽量规避。可以考虑打破上面的诱发条件,
针对条件1: 互斥条件基本上无法被破坏。因为线程需要通过互斥解决安全问题。
针对条件2:可以考虑一次性申请所有所需的资源,这样就不存在等待的问题
针对条件3:占用部分资源的线程在进一步申请其他资源时,如果申请不到,就主动释放掉已经占用的资源.
针对条件4:可以将资源改为线性顺序。申请资源时,先申请序号较小的,这样避免循环等待问题
除了使用synchronized同步机制处理线程安全问题之外,还可以使用jdk5.@提供的Lock锁的方式
1.:
步骤1,创建Lock的实例,需要确保多个线程共用同一个Lock实例!需要考虑将此对象声明为static final
步骤2.执行LockT方法,锁定对共享资源的调用
步骤3。 unlock(的调用,释放对共享数据的锁定
2。面试题:
synchronized同步的方式 与Lock的对比 ?
synchronized不管是同步代码块还是同步方法,都需要在结束一对{}之后,释放对同步监视器的调用Lock是通过两个方法控制需要被同步的代码,更灵活一些。Lock作为接口,提供了多种实现类,适合更多更复杂的场景,效率更高。