По прихоти - как написать тупик?

Java задняя часть Безопасность Eclipse

Только что закончил код проекта на руках, я взглянул на блог, а потом увидел ветку. Раньше была простая запись потоков и выполнения фрагментов.
Серия базовых знаний JAVA --- процесс, безопасность потоков

Когда я смотрел на это, я думал о том, как написать тупик. Когда я открыл eclipse, я вдруг почувствовал, что понятия не имею, что делать. Раньше я все время решал проблемы блокировки и тупика. немного странно писать тупик наоборот. . .

ок, напишите будет тупиковый сценарий, тупиковый и удовлетворяйте условиям.

  • Условие взаимного исключения: ресурс может использоваться только одним процессом одновременно.
  • Условия запроса и удержания: когда процесс блокируется запросом ресурсов, он будет удерживать полученные ресурсы.
  • Условие отсутствия лишения: ресурсы, полученные процессом, не могут быть принудительно лишены до тех пор, пока ресурсы не будут израсходованы.
  • Условие циклического ожидания: между несколькими процессами формируются отношения ресурсов циклического ожидания.

Во-первых, должны быть конкурирующие ресурсы, и оба потока должны одновременно ожидать освобождения ресурсов друг от друга. Итак, давайте сначала получим два ресурса:

Object lock=new Object();
Object lock2=new Object();

Тогда есть две темы:

Tr1 tr1=new Tr1(lock, lock2);
Tr2 tr2=new Tr2(lock, lock2);
		
Thread t1=new Thread(tr1);
Thread t2=new Thread(tr2);

запускать:

t1.start();
t2.start();

Итак, для блокировки, как lock2 создает отношения конкуренции внутри потока?Посмотрите на код:

package com.glmapper.base.synchronize;

public class Tr1 implements Runnable {
	
	Object lock;
	Object lock2;

	public Tr1(Object lock,Object lock2){
		this.lock= lock;
		this.lock2= lock2;
	}
	@Override
	public void run() {
	    //获取lock
		synchronized (lock) {
			System.out.println(Thread.currentThread().getName()+"获取了lock锁");
			try {
				Thread.sleep(3000);
			} catch (Exception e) {
			}
			//获取lock2
			synchronized (lock2) {
				System.out.println(Thread.currentThread().getName()+"获取了lock2锁");
			}
		}
		
	}
}


public class Tr2 implements Runnable {
	
	Object lock;
	Object lock2;

	public Tr2(Object lock,Object lock2){
		this.lock= lock;
		this.lock2= lock2;
	}
	@Override
	public void run() {
	    //获取lock2
		synchronized (lock2) {
			System.out.println(Thread.currentThread().getName()+"获取了lock2锁");
			try {
				Thread.sleep(3000);
			} catch (Exception e) {
			}
			//获取lock
			synchronized (lock) {
				System.out.println(Thread.currentThread().getName()+"获取了lock锁");
			}
		}
		
	}
}

Анализ: когда поток 1 получает блокировку, поток 2 получает блокировку lock2, затем поток 1 продолжает выполнение, и здесь

synchronized (lock2) {
	System.out.println(Thread.currentThread().getName()+"获取了lock2锁");
}

В этот момент необходимо получить блокировку lock2, но теперь lock2 удерживается потоком 2; в то же время поток 2 также начинает выполняться:

synchronized (lock) {
	System.out.println(Thread.currentThread().getName()+"获取了lock锁");
}

В это время поток 2 также пытается получить блокировку, но блокировка снова удерживается потоком 1. Оба потока ждут друг друга, чтобы освободить ресурсы, что приводит к взаимоблокировке. Готово. . .
Когда я собирался закрыться, я обнаружил, что все еще жду?

? ? Так почему? ? Что случилось под шоу ....

  • Давайте посмотрим на наш программный процесс через JPS
  • Используйте jstack -l [pid] для просмотра информации

Оба потока находятся в состоянии BLOCKED..., продолжайте смотреть вниз
найден 1 тупик, как мы и ожидали, тупик случился!