面试必问的多线程-1.2:线程-用Java实现死锁

news/2024/5/20 14:20:03 标签: 死锁, 面试

死锁面试必不可缺的知识点,

上节说的线程中已经很明确的说明了死锁的解决方案。

 

那么什么时候会有多线程问题?

1: 多线程的环境下

2: 必须有共享资源

3: 对资源进行非原子性操作

 

 

用Java怎么重现死锁呢?

 

例子:

有N个资源和N个线程,并且你需要所有的资源来完成一个操作

为了简单这里的n可以替换为2,越大的数据会使问题看起来更复杂。

通过避免Java中的死锁来得到关于死锁的更多信息。

/**

 * 简单死锁程序

 *      lockAlockB分别是两个资源线程AB必须同是拿到才能工作

 *     

                   但A线程先拿lockA、再拿lockB

 *                 线程B先拿lockB、再拿lockA

 

                   这样就导致了死锁,两个人都拿不到

 */

package net.health.ysk.admin;

/**
 * 用Java模拟死锁
 * 
 * @author wangtong
 */
public class DemoDeadLock {

	private Object object1 = new Object();
	private Object object2 = new Object();

	public void a() {
		System.out.println("a");
		synchronized (object1) {
			System.out.println("a-object1");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (object2) {
				System.out.println("a-object2");
			}
		}
	}

	public void b() {
		System.out.println("b");
		synchronized (object2) {
			System.out.println("b-object2");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (object1) {
				System.out.println("b-object1");
			}
		}
	}

	public static void main(String[] args) {
		DemoDeadLock demo = new DemoDeadLock();
		System.out.println("111111111111111111111");
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("a-run");
				demo.a();
			}
		}).start();;
		System.out.println("22222222222222222222222");
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("b-run");
				demo.b();
			}
		}).start();;
		System.out.println("333333333333333333333");
	}
}

执行该代码:

控制台打印结果:

111111111111111111111
22222222222222222222222
a-run
a
a-object1
333333333333333333333
b-run
b
b-object2

从这个打印结果就可以看出是发生了死锁,程序没有继续执行下去。

此时,a线程锁住了object1对象,正在等待,准备锁object2对象

b线程锁住了object2对象,正在登台,准备锁object1对象。

两个线程互相等待获取对方的锁,因此造成了死锁

通过jconsole也可以明显的查看到死锁了:

意思是  线程1,正在等待线程0上的68ad31fc的锁

 

 

 

 

 

 

 

 

 


http://www.niftyadmin.cn/n/1307917.html

相关文章

面试必问的多线程-1.3:lock和synchronized底层上有什么区别呢?

1)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。 Lock是一个类,通过这个类可以实现同步访问; 2)Lock和synchronized有一点非常大的不同, 采用synchronized不需要…

面试必问的多线程-1.4:各种锁介绍

认识的锁? 偏向锁 轻量级锁 重量级锁 重入锁 自旋锁 共享锁 独占锁\排它锁 读写锁 公平锁 非公平锁 死锁 活锁 1:偏向锁 是Java6引入的一项多线程优化,它会偏向于第一个访问锁的线程, 如果在运行过程中&#xff0c…

面试必问的Java-1.0:动态代理-静态代理

Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题。 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息&am…

分布式事务理解

事务是一组连续的操作,这一组操作要么都成功执行,要么都不能执行; 那么什么是数据库事务呢? 数据库事务一般具有以下几个特征: 原子性,构成事务的所有操作,要么都执行完成,要么全…

面试必问的数据库-3.1:索引-底层实现原理

索引可以加快查询的效率。 如果数据库没有加索引,sql中where是怎么执行查找到目标的? 举例: 如果想要查询表格第二列是怎么查找的? 如想查询where col222的记录,在没有加索引的情况下是按顺序从第一条记录开始查找&…

面试必问的数据库-3.2:索引-相关

1:数据库索引和选择性的关系 在讨论数据库索引的时候,经常会提到“选择性”(selectivity)这个概念。“选择性”是描述列值数据分布情况的一个重要属性。“选择性”和“基数”(cardinality)是两个密不可分的概念。“基数”就是一列中唯一值的数量&#x…

面试必问的数据库-4.1:sql-优化

1:关于批量插入数据(100万)数据优化 思路: 1:变多次提交为一次 2:使用批量操作 整理了两种方法: 方法一: 1. public static void insert() { 2. // 开时时间 3. …

面试必问的HashMap-1.1:HashMap几个关键点分析

HashMap都不算什么特别的,这里整理下我的理解。 分析HashMap就不得不说下数据结构, 首先Java中有几种数据结构:数组、链表、树 数组的话:查询效率高 链表新增效率高。 牛逼的是,我们的HashMap的数据接口就比较吊了…