多线程(3)

目录

    • 一、程序安全的单例模式之懒汉式
      • 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)

后续知识的学习及扩充

多线程(2)
多线程(4)


好了,我亲爱的读者朋友,以上就是本文的全部内容了!!!

觉得有点用记得给我点赞哦!

通过坚持不懈地学习,持续不断地输出,你的编程基本功算得上是突飞猛进。

为了帮助更多的程序员,专注于分享有趣的 Java 技术编程和有益的程序人生。一开始,阅读量寥寥无几,关注人数更是少得可怜。但随自己的不断努力,阅读量和关注人都在猛烈攀升。

绝对不容错过,期待与你的不期而遇。

你可能感兴趣的:(Java)