死锁


Java 默认线程有两个,main(主线程),GC(垃圾回收机制)

synchronized 关键字实现线程同步,让在访问同一个资源的多个线程排队去完成业务,避免出现数据错乱的情况。

死锁 DeadLock

前提:一个线程完成业务需要同时访问两个资源。

死锁:多个线程同时在完成业务,出现争抢资源的情况。

资源类

package com.southwind.demo1;

public class DeadLockRunnable implements Runnable {
	//编号
	public int num;
	//资源
	private static Chopsticks chopsticks1 = new Chopsticks();
	private static Chopsticks chopsticks2 = new Chopsticks();
	
	/**
	 * num = 1 拿到 chopsticks1,等待 chopsticks2
	 * num = 2 拿到 chopsticks2,等待 chopsticks1
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		if(num == 1) {
			System.out.println(Thread.currentThread().getName()+"拿到了chopsticks1,等待获取chopsticks2");
			synchronized (chopsticks1) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized (chopsticks2) {
					System.out.println(Thread.currentThread().getName()+"用餐完毕!");
				}
			}
		}
		if(num == 2) {
			System.out.println(Thread.currentThread().getName()+"拿到了chopsticks2,等待获取chopsticks1");
			synchronized (chopsticks2) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized (chopsticks1) {
					System.out.println(Thread.currentThread().getName()+"用餐完毕!");
				}
			}
		}
	}

}
package com.southwind.demo1;

public class DeadLockTest {
	public static void main(String[] args) {
		DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
		deadLockRunnable1.num = 1;
		DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
		deadLockRunnable2.num = 2;
		new Thread(deadLockRunnable1,"张三").start();
		new Thread(deadLockRunnable2,"李四").start();
	}
}

如何破解死锁

不要让多线程并发访问

package com.southwind.demo1;

public class DeadLockTest {
  public static void main(String[] args) {
    DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
    deadLockRunnable1.num = 1;
    DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
    deadLockRunnable2.num = 2;
    new Thread(deadLockRunnable1,"张三").start();
    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    new Thread(deadLockRunnable2,"李四").start();
  }
}

使用 lambda 表达式简化代码开发

package com.southwind.demo2;

public class Test3 {
	public static void main(String[] args) {
		//lambda表达式
		new Thread(()->{
			for(int i=0;i<100;i++) {
				System.out.println("+++++++++++Runnable");
			}
		}) .start();
	}
}
package com.southwind.demo2;

public class Test3 {
  public static void main(String[] args) {
    new Thread(()->{for(int i=0;i<100;i++) System.out.println("+++++++Runnable");}).start();
    new Thread(()->{for(int i=0;i<100;i++) System.out.println("----Runnable");}).start();
    new Thread(()->{for(int i=0;i<100;i++) System.out.println("++++=====++Runnable");}).start();
  }
}

Lock

JUC

java.util.concurrent

Lock 是一个接口,用来实现线程同步的,功能与 synchronized 一样。

Lock 使用频率最高的实现类是 ReentrantLock(重入锁),可以重复上锁。

package com.southwind.demo3;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test2 {
	public static void main(String[] args) {
		Account account = new Account();
		new Thread(account,"A").start();
		new Thread(account,"B").start();
	}
}

class Account implements Runnable{

	private static int num;
	private Lock lock = new ReentrantLock();
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		lock.lock();
		num++;
		System.out.println(Thread.currentThread().getName()+"是当前的第"+num+"位访客");
		lock.unlock();
	}
	
}

实现资源和 Runnable 接口的解耦合。

package com.southwind.demo3;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test2 {
  public static void main(String[] args) {
    Account account = new Account();
    new Thread(()->{
      account.count();
    },"A").start(); 
    new Thread(()->{
      account.count();
    },"B").start(); 
  }
}

class Account {
  private int num;
  private Lock lock = new ReentrantLock();

  public void count() {
    lock.lock();
    num++;
    System.out.println(Thread.currentThread().getName()+"是第"+num+"位访客");
    lock.unlock();
  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值