java多线程学习(二)——死锁的产生

news/2024/5/20 15:39:30 标签: 多线程, 死锁

多线程死锁产生的原因:在同步代码中嵌套同步,导致多线程访问的时候,锁无法被释放,产生思索。
举例代码:

package com.dss.test;

class ThreadTran1 implements Runnable{

	private static int total = 100;
	public boolean flag = true;
	
	public Object object = new Object();
	
	@Override
	public void run() {
		if(flag) {
			while(true) {
				synchronized (object) {
					sale();
				}
			}
			
		}else {
			
			while(true) {
				try {
					Thread.sleep(40);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				sale();
			}
		}
		
	}
	
	public synchronized void sale() {
		synchronized (this) {
			if(total > 0) {
				System.out.println(Thread.currentThread().getName() + "出售第 " + (100-total+1) + "张票");
				total--;
			}
		}
		
	}
	
}

public class ThreadDemo {

	public static void main(String[] args) {
		ThreadTran1 threadTran1 = new ThreadTran1();
		Thread t1 = new Thread(threadTran1,"线程1");
		
		Thread t2 = new Thread(threadTran1,"线程2");
		t1.start();
		
		try {
			Thread.sleep(400);
		}catch(Exception e) {
			
		}
		
		threadTran1.flag = false;
		t2.start();
	}
	
}

说明:
线程一启动之后,要先拿到 object 这个对象锁,之后要进入 sale() 方法,此时又要拿到 this 锁
而线程二启动之后,先进入 sale() 方法,先要拿到 this 锁,之后在 sale() 方法里面,有同步代码块,此时又要再拿 object 对象锁
当线程一先拿到 object 锁,线程二 先拿到 this 锁,此时线程一要再获取 this 锁,线程二要再获取 object 锁,但是都获取不到了,所以他们只能等锁被释放,但是锁永远不会被释放,这样,死锁就产生了


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

相关文章

Spring Boot学习笔记(7)—— SpringBoot项目自定义欢迎页

1、前面在 https://blog.csdn.net/weixin_43231076/article/details/90142888 中提到,springboot项目的默认欢迎页是放在 4个静态资源目录 下面,在访问:localhost:8080 或者 localhost:8080/index.html 请求时,会从4个静态资源目录…

Spring Boot学习笔记(8)——国际化信息

SprintBoot国际化步骤 1、编写国际化配置文件,将需要国际化显示的内容写在配置文件中 1)、在类路径下面,创建一个文件夹:i18n 2)、在文件夹 i18n 中创建一个默认的国际化文件:login.properties&#xff08…

java多线程学习(三)——线程之间的通讯以及Lock锁

多线程之间的通讯 什么是多线程之间的通讯:就是多个线程操作同一资源,但是操作不同,要求一个线程的操作对另一个线程产生影响 需求:两个线程,第一个线程对一个对象进行写操作,第二个线程对该对象进行读的操…

Spring Boot学习笔记(8)—— SpringBoot自定义拦截器

拦截器在实际项目开发中很重要,下面以登录拦截器为例,要用户登录才能访问系统中的请求 1、自定义一个拦截器 LoginHandlerInterceptor,实现 HandlerInterceptor接口,重写里面的 preHandle方法: import javax.servlet.…

java多线程学习(四)—— ConcurrentHashMap和CountDownLatch的使用

ConcurrentHashMap 1、在jdk中,我们常用的map集合是 HashTable 和 HashMap 这两个,其中HashTable是线程安全的,即里面的每一个方法都是线程同步的方法,使用了synchronized关键字修饰,而HashMap是线程不安全的。 2、虽…

java多线程学习(五)—— java并发队列

基本定义 1、在jdk1.5并发包中,对于并发队列提供了两套实现,一个是以 ConcurrentLinkedDeque为代表的高性能队列,它是无边界的,非阻塞式的队列;一个是以 BlockingQueue接口为代表的阻塞队列,它的主要实现类…

java多线程学习(六)—— 线程池

什么是线程池 Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处。 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消…

Spring Boot学习笔记(9)—— SpringBoot自定义错误处理

springBoot默认的错误处理机制 浏览器发送一个不存在的请求时,会报404,浏览器出现springboot默认的404错误页面 如果是服务器内部出现错误,则抛出500错误页面 springBoot默认错误机制底层原理分析 底层原理关注 ErrorMvcAutoConfigurati…