138-多线程-线程安全的懒汉式_死锁_ReentrantLock的使用

package cd_one.code12.exer9;

import java.awt.*;

//实现线程安全的懒汉式
public class BankTest {
    static Bank b1 = null;
    static Bank b2 = null;

    public static void main(String[] args) {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                b1 = Bank.getInstance();
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                b2 = Bank.getInstance();
            }
        };
        t1.start();
        t2.start();


        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(b1);
        System.out.println(b2);
        System.out.println(b1 == b2);
    }
}
class Bank{
    private  Bank(){}
    private  static volatile Bank instance = null;
    //线程安全的第一种方式
//    public static synchronized Bank getInstance() { //当前类本身,默认为Bank.class
//        if(instance == null){
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            instance = new Bank();
//        }
//        return instance;
//    }
    //线程安全的第2种方式
//    public static Bank getInstance(){
//        synchronized (Bank.class){
//            if(instance == null){
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                instance = new Bank();
//            }
//
//        }return instance;
//        }
//线程安全的第3种方式:相较于1,和2,效率更高,为了避免出现指令重排,需要将instance声明为volatile
    public static Bank getInstance(){
        if(instance == null) {
            synchronized (Bank.class) {
                if (instance == null) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new Bank();
                }
            }
        }
        return instance;
        }

}

运行结果

cd_one.code12.exer9.Bank@880ec60
cd_one.code12.exer9.Bank@880ec60
true

线程不安全的例子

结果

package cd_one.code12.exer10;

import java.util.concurrent.locks.ReentrantLock;

class Window extends Thread{
    static int ticket = 100;
//    1、创建lock的实例,需要确保多个线程共用同一个Lock实例!需要考虑将此对象声明为static final
    private static final ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {
        while(true){
            synchronized (Window.class){
                try{
                    lock.lock();//锁定对共享资源的调用
                    if(ticket > 0){

                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);
                        ticket--;
                    }else{
                        break;
                    }
                }finally {
//                    3.unlock()的调用,释放对共享数据的锁定
                    lock.unlock();
                }

            }
        }
    }
}
public class LockTest {
    public static void main(String[] args) {

        Window w1 = new Window();
        Window w2 = new Window();
        Window w3 = new Window();
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");
        w1.start();
        w2.start();
        w3.start();

    }
}

窗口3售票,票号为:76
窗口2售票,票号为:75
窗口3售票,票号为:74
窗口3售票,票号为:73
窗口1售票,票号为:72
窗口1售票,票号为:71
窗口1售票,票号为:70
窗口1售票,票号为:69
窗口3售票,票号为:68
窗口2售票,票号为:67
窗口3售票,票号为:66
窗口3售票,票号为:65
窗口3售票,票号为:64
窗口1售票,票号为:63
窗口1售票,票号为:62
窗口3售票,票号为:61
窗口3售票,票号为:60
窗口2售票,票号为:59
窗口2售票,票号为:58
窗口2售票,票号为:57
窗口2售票,票号为:56
窗口2售票,票号为:55
窗口3售票,票号为:54
窗口1售票,票号为:53
窗口3售票,票号为:52
窗口3售票,票号为:51
窗口3售票,票号为:50
窗口2售票,票号为:49
窗口3售票,票号为:48
窗口1售票,票号为:47
窗口1售票,票号为:46
窗口3售票,票号为:45
窗口3售票,票号为:44
窗口2售票,票号为:43
窗口3售票,票号为:42
窗口3售票,票号为:41
窗口3售票,票号为:40
窗口3售票,票号为:39
窗口3售票,票号为:38
窗口3售票,票号为:37
窗口3售票,票号为:36
窗口3售票,票号为:35
窗口3售票,票号为:34
窗口3售票,票号为:33
窗口3售票,票号为:32
窗口3售票,票号为:31
窗口3售票,票号为:30
窗口1售票,票号为:29
窗口3售票,票号为:28
窗口2售票,票号为:27
窗口2售票,票号为:26
窗口2售票,票号为:25
窗口2售票,票号为:24
窗口3售票,票号为:23
窗口1售票,票号为:22
窗口1售票,票号为:21
窗口1售票,票号为:20
窗口1售票,票号为:19
窗口3售票,票号为:18
窗口3售票,票号为:17
窗口2售票,票号为:16
窗口2售票,票号为:15
窗口2售票,票号为:14
窗口2售票,票号为:13
窗口2售票,票号为:12
窗口3售票,票号为:11
窗口1售票,票号为:10
窗口1售票,票号为:9
窗口1售票,票号为:8
窗口1售票,票号为:7
窗口3售票,票号为:6
窗口3售票,票号为:5
窗口3售票,票号为:4
窗口3售票,票号为:3
窗口3售票,票号为:2
窗口2售票,票号为:1

运行结果如上

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃炫迈的绮绮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值