多线程(3)

    技术2022-07-11  84

    目录

    一、程序安全的单例模式之懒汉式1. 通过同步代码块解决懒汉式单例设计模式的线程安全问题2.通过同步方法解决懒汉式单例设计模式的线程安全问题 二、死锁问题1.死锁的理解:2.说明: 三、Lock锁方式解决线程安全问题


    一、程序安全的单例模式之懒汉式

    1. 通过同步代码块解决懒汉式单例设计模式的线程安全问题

    使用同步机制将单例模式中的懒汉式改写为线程安全的

    代码实现:

    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; } }

    2.通过同步方法解决懒汉式单例设计模式的线程安全问题

    通过同步方法解决懒汉式单例设计模式的线程安全问题

    代码实现:

    class Bank { private static Bank instance = null; public synchronized Bank getInstance() { if (instance == null) { instance = new Bank(); } return instance; } }

    二、死锁问题

    1.死锁的理解:

    不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。

    2.说明:

    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锁方式解决线程安全问题

    解决线程安全问题的方式三: 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


    如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。 创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客
    Processed: 0.009, SQL: 9