Java实现死锁的两种实现以及无限调用的synchronized
程序员文章站
2022-03-29 19:25:26
...
目录
现在这个模式:存在什么样的问题:
我们都是demo:但是却对妙的方法没有研究,没有感觉
解决:死锁的不同的原理的demo:
1.显示定义一个线程的方法
代码逻辑:
多线程死锁的本质: * 和synchronized 中的new object类似 * 直接new object1 object2 * <p> * thread1 :lock(1) ---> thread.sleep() ----->lock(2) * thread2 :lock(2) ---> thread.sleep() ----->lock(1) * p> * 同时多个线程要达到同时启动的效果,且会根据区分执行以上的流程: * 如果在一个线程方法里面,需要一个 flag * 否则就需要多个线程逻辑,(这个时候如果需要共用object,那么可以内部类实现!) * <p>
代码展示:
package com.special.thread.javamulthreadbook;
import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
/**
* @author liuYC
* @ClassName DeadLockDemo2
* @Description TODO
* @date 2021/7/22 16:27
* <p>
* 多线程死锁的本质:
* 和synchronized 中的new object类似
* 直接new object1 object2
* <p>
* thread1 :lock(1) ---> thread.sleep() ----->lock(2)
* thread2 :lock(2) ---> thread.sleep() ----->lock(1)
* p>
* 同时多个线程要达到同时启动的效果,且会根据区分执行以上的流程:
* 如果在一个线程方法里面,需要一个 flag
* 否则就需要多个线程逻辑,(这个时候如果需要共用object,那么可以内部类实现!)
* <p>
* 为什么验证的时候,输出的结果总是没有死锁了:
* name = a
* name = b
* execute lock2 ------> lock1
* execute lock1 ------> lock2
* name = b
* execute lock2 ------> lock1
*/
public class DeadLockDemo2 {
// @SneakyThrows
public static void main(String[] args) {
DeadThread deadThread = new DeadThread();
deadThread.setFlag("a");
Thread thread1 = new Thread(deadThread);
thread1.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
deadThread.setFlag("b");
Thread thread2 = new Thread(deadThread);
thread2.start();
/*deadThread.setFlag("b");
Thread thread2 = new Thread(deadThread);
thread2.start();*/
}
}
class DeadThread implements Runnable {
public Object object1 = new Object();
public Object object2 = new Object();
public String name;
public void setFlag(String name) {
this.name = name;
}
// @SneakyThrows
@Override
public void run() {
if (StringUtils.equals(name, "a")) {
synchronized (object1) {
System.out.println("name = " + name);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (object2) {
System.out.println("execute lock1 ------> lock2");
}
}
if (StringUtils.equals(name, "b")) {
synchronized (object2) {
System.out.println("name = " + name);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (object1) {
System.out.println("execute lock2 ------> lock1");
}
}
}
}
运行结果:
* name = a * name = b * execute lock2 ------> lock1 * execute lock1 ------> lock2 * name = b * execute lock2 ------> lock1
2.显示定义两个线程的方法:原理同第一个
代码逻辑:
同第一个,只不过是两个线程的定义的实现方法:
代码展示:
参考文章
运行结果:
3.synchronized实现的无限循环的demo
代码逻辑:
* 的代码证明: 无限等待方法的解决 * 本质就是new object * synchronized()代码块的时候,锁的对象是不同的对象实例 *
代码展示:
package com.special.thread.javamulthreadbook;
import javax.swing.text.StyledEditorKit;
/**
* @author liuYC
* @ClassName DeadlockDemo1
* @Description TODO
* @date 2021/7/22 15:27
* <p>
* 的代码证明: 无限等待方法的解决
* 本质就是new object
* synchronized()代码块的时候,锁的对象是不同的对象实例
*
* 案例,
* 单线程和多线程的区别,注意
*/
public class DeadlockDemo1 {
public static void main(String[] args) {
final DeadService deadService = new DeadService();
final DeadThreadA deadThreadA = new DeadThreadA(deadService);
final DeadThreadB deadThreadB = new DeadThreadB(deadService);
deadThreadA.start();
deadThreadB.start();
}
}
class DeadThreadA extends Thread {
private DeadService deadService;
public DeadThreadA(DeadService deadService) {
this.deadService = deadService;
}
@Override
public void run() {
super.run();
deadService.deadMethodA();
}
}
class DeadThreadB extends Thread {
private DeadService deadService;
//构造方法,初始化传入目标对象,进行返回的调用
public DeadThreadB(DeadService deadService) {
this.deadService = deadService;
}
@Override
public void run() {
super.run();
deadService.deadMethodB();
}
}
class DeadService {
// method a 会造成死锁
public void deadMethodA() {
System.out.println("=========thread A begin========");
boolean flag = true;
while (flag) {
}
System.out.println("=========thread A end========");
}
// method b正常的方法!
public void deadMethodB() {
System.out.println("=========thread B begin========");
System.out.println("=========thread B end========");
}
}
运行结果:
=========thread B begin========
=========thread B end========
=========thread A begin========
结论可以看到没有显示:thread a end解决方法也很简单:
两个方法里面,锁住代码块的方法