• day14 线程4 同步机制的单例模式懒汉式 和 死锁问题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; //告诉以后的线程不用等了,直接返回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();


    }


    }

    package com.atguigu.java1;
    //死锁的演示
    class A {
    public synchronized void foo(B b) { //同步监视器:A类的对象:a              同步方法的方式,用的锁是A的对象
    System.out.println("当前线程名: " + Thread.currentThread().getName()
    + " 进入了A实例的foo方法"); // ①
    // try {
    // Thread.sleep(200);
    // } catch (InterruptedException ex) {
    // ex.printStackTrace();
    // }
    System.out.println("当前线程名: " + Thread.currentThread().getName()
    + " 企图调用B实例的last方法"); // ③
    b.last();
    }

    public synchronized void last() {//同步监视器:A类的对象:a
    System.out.println("进入了A类的last方法内部");
    }
    }

    class B {
    public synchronized void bar(A a) {//同步监视器:b
    System.out.println("当前线程名: " + Thread.currentThread().getName()
    + " 进入了B实例的bar方法"); // ②
    // try {
    // Thread.sleep(200);
    // } catch (InterruptedException ex) {
    // ex.printStackTrace();
    // }
    System.out.println("当前线程名: " + Thread.currentThread().getName()
    + " 企图调用A实例的last方法"); // ④
    a.last();
    }

    public synchronized void last() {//同步监视器:b
    System.out.println("进入了B类的last方法内部");
    }
    }

    public class DeadLock implements Runnable {
    A a = new A();
    B b = new B();

    public void init() {
    Thread.currentThread().setName("主线程");
    // 调用a对象的foo方法
    a.foo(b);
    System.out.println("进入了主线程之后");
    }

    public void run() {
    Thread.currentThread().setName("副线程");
    // 调用b对象的bar方法
    b.bar(a);
    System.out.println("进入了副线程之后");
    }

    public static void main(String[] args) {
    DeadLock dl = new DeadLock();             //分线程,执行run()
    new Thread(dl).start();                                 //start()开始调run()


    dl.init();              //主线程,调用init().
    }
    }

  • 相关阅读:
    demo 集合
    iOS12、iOS11、iOS10、iOS9常见适配
    gem install cocoapods ERROR: While executing gem ... (Gem::FilePermissionError)
    ios LaunchScreen.storyboard 适配启动图
    加载资源文件读取以及转换成字符串的方法
    [UIApplication sharedApplication].keyWindow和[[UIApplication sharedApplication].delegate window]区别
    婚庆手机APP
    从一部电视剧开始
    论一次使用代理模式实现共用导出报表的功能
    MySql中使用EXPLAIN查看sql的执行计划
  • 原文地址:https://www.cnblogs.com/wangyanbin2333/p/13446481.html
Copyright © 2020-2023  润新知