zoukankan      html  css  js  c++  java
  • 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().
    }
    }

  • 相关阅读:
    C++句柄类 [ 资深博主 ]
    [C/C++] 第18章:特殊工具与技术《 C++ Primer 》
    [C/C++] 读后的感觉《C++Primer》
    Oracle个人Blogs精华贴
    Oracle安装图解
    [转]怎么成为优秀的软件模型设计者
    如何写一份好的工程师简历[转载]
    如何准备软件工程师的面试[转载]
    JS倒计时
    10个最有前景的JavaScript框架
  • 原文地址:https://www.cnblogs.com/wangyanbin2333/p/13446481.html
Copyright © 2011-2022 走看看