>  기사  >  Java  >  자바의 교착상태

자바의 교착상태

WBOY
WBOY원래의
2024-08-30 15:40:06841검색

Java에서 교착상태는 스레드 1이 스레드 2가 획득한 객체 잠금을 기다리고, 스레드 2가 스레드 1이 획득한 객체 잠금을 기다리는 멀티스레딩 상황입니다. 여기서 스레드 1과 스레드 2는 모두 서로를 기다립니다. 잠금을 해제합니다. Java의 다중 스레드 프로그램은 언급된 개체와 연결된 모니터나 잠금을 기다리는 동안 동기화 키워드가 실행 스레드를 차단하므로 교착 상태를 일으킬 수 있습니다. 다음 섹션에서 Deadlock의 작동 및 예를 살펴보겠습니다.

무료 소프트웨어 개발 과정 시작

웹 개발, 프로그래밍 언어, 소프트웨어 테스팅 등

교착상태는 어떻게 작동하나요?

논의한 대로 동기화 방법은 코드의 특정 부분을 잠글 수 있습니다. Java의 각 개체에는 잠금이 있으며 동기화는 한 번에 하나의 스레드만 해당 기능이나 코드 블록에 액세스할 수 있도록 기능이나 코드 블록을 잠그는 기술입니다.

특정 스레드가 동기화된 기능을 실행해야 할 때 먼저 잠금을 얻으려고 시도합니다. 동시에 다른 스레드가 이미 잠금을 수신한 경우 첫 번째 스레드는 스레드 2가 잠금을 해제할 때까지 기다립니다. 동기화를 통해 데이터 불일치 문제를 방지하더라도 동기화 문제가 있습니다.

'스레드 1'과 '스레드 2'라는 2개의 스레드가 있다고 가정합니다. 스레드 1은 개체 1의 잠금을 획득했고 스레드 2는 개체 2의 잠금을 획득했습니다. 메서드 1을 실행하는 스레드 1은 개체 2의 잠금을 획득하려고 합니다. 그러나 스레드 2는 이미 개체 2의 잠금을 획득했습니다.

또한 스레드 2는 개체 1에 대한 잠금을 획득해야 합니다. 그러나 스레드 1은 개체 1에 대한 잠금을 가지고 있습니다. 여기서 스레드 1과 스레드 2 모두 실행을 완료할 수 없으며 잠금을 영원히 기다릴 수 없습니다. 이런 상황을 교착상태(Deadlock)라고 합니다.

Java 교착상태의 예

다음은 언급된 예입니다.

예시 #1

Deadlock을 구현하기 위한 Java 프로그램

코드:

public class DeadLockExample {
//main method
public static void main(String[] args) throws InterruptedException {
//create three objects 1, 2 and 3
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
//create three threads 1, 2 and 3
Thread th1 = new Thread(new SynchronizationThread(o1, o2), "thread 1");
Thread th2 = new Thread(new SynchronizationThread(o2, o3), "thread 2");
Thread th3 = new Thread(new SynchronizationThread(o3, o1), "thread 3");
//start thread 1
th1.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
//start thread 2
th2.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
//start thread 3
th3.start();
}
}
class SynchronizationThread implements Runnable
{
private Object o1;
private Object o2;
public SynchronizationThread(Object o1, Object o2){
this.o1=o1;
this.o2=o2;
}
//function run
@Override
public void run() {
//store the name of the thread
String nm = Thread.currentThread().getName();
System.out.println( nm + " attaining lock on "+ o1 ) ;
synchronized (o1)
{
System.out.println( nm + " attained lock on "+ o1 ) ;
work();
System.out.println( nm + " attaining lock on "+ o2 ) ;
synchronized (o2) {
System.out.println( nm + " attained lock on "+ o2 );
work();
}
System.out.println( nm + " released lock on "+ o2 ) ;
}
System.out.println( nm + " released lock on "+ o1 ) ;
System.out.println( nm + " completed execution.") ;
}
//function work
private void work() {
try {
//thread sleeps
Thread.sleep(30000);
}
//catch the exception
catch (InterruptedException exc)
{
exc.printStackTrace();
}
}
}

출력:

자바의 교착상태

예시 #2

이 프로그램에서는 실행 중인 3개의 스레드가 리소스를 공유하며 개체 1에 대한 잠금을 획득하는 방식으로 실행되지만 개체 2에 대한 잠금을 얻으려고 하면 대기 상태가 됩니다. Deadlock을 방지하려면 다음과 같이 코드를 다시 작성하면 됩니다.

코드:

public class DeadLockExample {
public static void main(String[] args) throws InterruptedException {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
Thread th1 = new Thread(new SynchronizationThread(o1, o2), "thread 1");
Thread th2 = new Thread(new SynchronizationThread(o2, o3), "thread 2");
Thread th3 = new Thread(new SynchronizationThread(o3, o1), "thread 3");
//start thread 1, 2 and 3
th1.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
th2.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
th3.start();
}
}
class SynchronizationThread implements Runnable{
private Object o1;
private Object o2;
public SynchronizationThread(Object o1, Object o2){
this.o1=o1;
this.o2=o2;
}
//function run
@Override
public void run() {
//store the name of the thread
String nm = Thread.currentThread().getName();
System.out.println( nm + " attaining lock on "+ o1 ) ;
synchronized (o1)
{
System.out.println( nm + " attained lock on "+ o1 ) ;
work();
}
System.out.println( nm + " released lock on "+ o1 ) ;
System.out.println( nm + " acquiring lock on " + o2 );
synchronized (o2) {
System.out.println( nm + " attained lock on "+ o2 );
work();
}
System.out.println( nm + " released lock on "+ o2 ) ;
System.out.println( nm + " released lock on "+ o1 ) ;
System.out.println( nm + " completed execution.") ;
}
//function work
private void work() {
try {
//thread sleeps
Thread.sleep(30000);
}
//catch the exception
catch (InterruptedException exc)
{
exc.printStackTrace();
}
}
}

출력:

자바의 교착상태

Java에서 교착 상태를 피하는 방법은 무엇입니까?

다음은 교착 상황을 방지하는 데 도움이 되는 지침입니다.

1. 중첩된 잠금을 피하세요

중첩된 잠금은 교착 상태를 일으키는 일반적인 원인 중 하나입니다. 교착 상태를 방지하려면 이미 리소스를 보유하고 있는 경우 다른 리소스를 잠그지 마세요. 사용자가 1개의 개체로만 작업하는 경우 교착 상태가 발생할 수 없습니다.

2. 필요한 것만 잠그세요

필요한 리소스만 잠그는 것이 좋습니다. 그러나 일부 사용자는 필요하지 않은 경우에도 리소스를 잠그려고 시도할 수 있습니다.

3. 무한정 기다리지 마세요

두 스레드가 스레드 조인의 도움으로 서로가 무기한 완료되기를 기다리면 교착 상태가 발생합니다. 스레드가 다른 스레드가 완료될 때까지 기다려야 하는 경우 스레드가 완료될 때까지 기다려야 하는 최대 시간으로 조인을 사용하는 것이 좋습니다.

위 내용은 자바의 교착상태의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:자바 getMethod()다음 기사:자바 getMethod()