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().
}
}

原文地址:https://www.cnblogs.com/wangyanbin2333/p/13446481.html