Java 基础(线程的死锁问题)
- 死锁
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续
- 解决方法
专门的算法、原则
尽量减少同步资源的定义
尽量避免嵌套同步
例子一:
package com.klvchen.java1; /** * @author klvchen * @create 2021-04-12-15:21 */ 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.klvchen.java1; class A{ public synchronized void foo(B b) {//同步监视器:A类的对象:a System.out.println("当期线程名: " + Thread.currentThread().getName() + " 进入A实例的 foo 方法"); try { Thread.sleep(100); } catch (InterruptedException e){ e.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(100); } catch (InterruptedException e){ e.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("副线程"); //调用对象的 bar 方法 b.bar(a); System.out.println("进入了副线程之后"); } public static void main(String[] args) { DeadLock dl = new DeadLock(); new Thread(dl).start(); dl.init(); } }

浙公网安备 33010602011771号