简述多线程中的死锁以及thread.join
死锁
java中导致死锁的原因
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,而该资源又被其他线程锁定,从而导致每一个线程都得等其它线程释放其锁定的资源,造成了所有线程都无法正常结束。这是从网上其他文档看到的死锁产生的四个必要条件:
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用 2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。 3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。 4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。 当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。
代码demo
public class DeadLock { private static String A = "A"; private static String B = "B"; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized (A) { try { System.out.println("线程一拿到A锁"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (B) { System.out.println("线程一拿到B锁"); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized (B) { try { System.out.println("线程二拿到B锁"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (A) { System.out.println("线程二拿到A锁"); } } } }); //启动线程 t1.start(); t2.start(); } }
避免死锁的几个常见方法: 1.避免一个线程同时获取多个锁。 2.避免在一个资源内占用多个 资源,尽量保证每个锁只占用一个资源。 3.尝试使用定时锁,使用tryLock(timeout)来代替使用内部锁机制。 4.对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。 5.避免同步嵌套的发生
Thread.join
join()方法是Thread类中的一个方法,该方法的定义是等待该线程终止。其实就是join()方法将挂起调用线程的执行,直到被调用的对象完成它的执行
public class JoinDemo { public static void main(String[] args) { //初始化线程t1,由于后续有匿名内部类调用这个对象,需要用final修饰 final Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("t1 is running"); } }); //初始化线程t2,由于后续有匿名内部类调用这个对象,需要用final修饰 final Thread t2 = new Thread(new Runnable() { @Override public void run() { try { //t1调用join方法,t2会等待t1运行完之后才会开始执行后续代码 t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("t2 is running"); } } }); //初始化线程t3 Thread t3 = new Thread(new Runnable() { @Override public void run() { try { //t2调用join方法,t3会等待t2运行完之后才会开始执行后续代码 t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("t3 is running"); } } }); //依次启动3个线程 t1.start(); t2.start(); t3.start(); } }
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
python自动化生成请假条