使用同步机制将单例模式中的懒汉式改写为线程安全的
代码实现:
public class BankTest { } class Bank{ private Bank(){} private static Bank instance = null; public static Bank getInstance(){ //方式一:效率稍差 // synchronized (Bank.class){ // if (instance == null){ // instance = new Bank(); // } // return instance; // } //方式二:效率更高 //先判断是否为空,如果为空,进行锁住,否则可以直接获取该对象。 if (instance ==null){ synchronized (Bank.class){ if (instance == null){ instance = new Bank(); } } } return instance; } }通过同步方法解决懒汉式单例设计模式的线程安全问题
代码实现:
class Bank { private static Bank instance = null; public synchronized Bank getInstance() { if (instance == null) { instance = new Bank(); } return instance; } }不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。
1)出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续。 2)我们使用同步时,要避免出现死锁。
代码实现:
public class ThreadTest { public static void main(String[] args) { StringBuffer s1 = new StringBuffer(); StringBuffer s2 = new StringBuffer(); new Thread(){ @Override public void run() { synchronized (s1){ s1.append("a"); s2.append("1"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (s2){ s1.append("b"); s2.append("2"); System.out.println(s1); System.out.println(s2); } } } }.start(); new Thread(new Runnable() { @Override public void run() { synchronized (s2){ s1.append("c"); s2.append("3"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (s1){ s1.append("d"); s2.append("4"); System.out.println(s1); System.out.println(s2); } } } }).start(); } }运行结果: ab 12 abcd 1234
解决线程安全问题的方式三: Lock锁 — JDK5.0新增
优先使用顺序: Lock -> 同步代码块(已经进入了方法体,分配了相应资源) -> 同步方法(在方法体之外)
代码实现:
public class LockTest { public static void main(String[] args) { Window w = new Window(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } } class Window implements Runnable{ private int ticket = 100; //1.实例化ReentrantLock private ReentrantLock lock = new ReentrantLock(); @Override public void run() { while (true){ try { //2.调用锁定方法lock() lock.lock(); if (ticket >0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": 售票,票号为:" + ticket); ticket--; }else{ break; } }finally { //3.调用解锁方法unlock() lock.unlock(); } } } }多线程知识的学习
多线程(1):https://blog.csdn.net/weixin_45606067/article/details/107067785 多线程(2):https://blog.csdn.net/weixin_45606067/article/details/107067802 多线程(4):https://blog.csdn.net/weixin_45606067/article/details/107068938