Java 프로그래머 면접에서의 다중 스레드 문제 요약

많은 핵심 자바 면접 문제는 다중 스레드(Multi-Threading)와 집합 프레임워크(Collections Framework)에서 유래한 것으로 핵심 스레드 개념을 이해할 때 숙련된 실제 경험이 필수적이다.이 글은 자바 라인에 관한 전형적인 문제들을 수집했는데, 이런 문제들은 자주 고급 엔지니어에게 묻힌다.
0, Java의 다중 스레드 동기화는 무엇입니까?
다중 루틴 프로그램에서 동기화는 공유 자원에 대한 접근을 제어할 수 있다.동기화가 없으면 Java 스레드가 공유 변수를 수정할 때 다른 스레드가 같은 변수를 사용하거나 업데이트하고 있기 때문에 프로그램에 오류가 발생하기 쉽습니다.
1. 다중 스레드를 실현하는 몇 가지 방법을 설명합니까?
자바 라인은 Runnable 인터페이스나 Thread 클래스를 계승하여 실현할 수 있으며, 다중 계승을 계획할 때 Runnable를 우선적으로 선택하십시오.
2、Thread.start() 및 Thread.run()은 어떤 차이가 있습니까?
Thread.start () 방법 (native) 은 라인을 시작하여 준비 상태로 들어가게 합니다. cpu가 이 라인을 분배할 때 JVM 스케줄링으로 run () 방법을 실행합니다.
3. 왜 런 () 과 start () 방법이 필요합니까? 우리는 런 () 방법으로만 임무를 완성할 수 있습니까?
run () & start () 이 두 가지 방법이 필요합니다. JVM이 단독 라인을 만드는 것은 일반적인 방법과 다른 호출이기 때문에 이 작업은 라인의 start 방법으로 이루어집니다. start는 로컬 방법으로 이루어지고 디스플레이로 호출되어야 합니다. 이 두 가지 방법을 사용하는 또 다른 장점은 어떤 대상이든 라인으로 실행할 수 있다는 것입니다. Runnable 인터페이스만 실현된다면이로써 Thread 클래스를 계승했기 때문에 Java의 다중 계승 문제를 피할 수 있다.
4. ThreadLocal 클래스는 무엇이며 어떻게 사용합니까?
ThreadLocal은 로컬 스레드가 아닌 스레드 수준의 로컬 변수입니다.ThreadLocal은 이 변수를 사용하는 모든 라인에 독립된 변수 복사본을 제공합니다. 각 스레드가 복사본을 수정할 때 다른 스레드 대상의 복사본에 영향을 주지 않습니다.
다음은 스레드 부분 변수(ThreadLocal variables)의 핵심 포인트입니다.
하나의 스레드 부분 변수(ThreadLocal variables)는 모든 스레드에 단독 변수를 편리하게 제공합니다.
ThreadLocal 실례는 정적 개인 (private static) 필드로 한 클래스에 나타나는데, 이 클래스는 하나의 라인을 연결하는 데 사용됩니다.
여러 개의 스레드가 ThreadLocal 실례에 접근할 때, 각 스레드는ThreadLocal에서 제공하는 독립된 변수 복사본을 유지합니다.
자주 사용하는 사용은 DAO 모드에서 볼 수 있다. DAO 클래스가 하나의 예 클래스일 때 데이터베이스 링크(connection)는 모든 라인에 독립적으로 유지보수되고 서로 영향을 주지 않는다.(스레드 기반 단례)
5, 언제 Invalid Monitor State Exception 이상을 던져, 왜?
wait ()/notify ()/notify All () 의 모든 방법을 호출할 때, 현재 라인이 이 대상의 자물쇠를 얻지 못하면, Illegal MonitorState Exception의 이상을 던집니다. (즉, 프로그램이 대상의 동기화 블록이나 동기화 방법을 실행하지 않았을 때,wait ()/notify ()/notify All () 를 호출하려고 시도할 때)이 이상은 Runtime Excpetion의 하위 클래스이기 때문에 반드시 포착해야 하는 것은 아니다.RuntimeException으로서 이러한 이상은wait(), notify(), notifyAll()의 방법에 서명하지 않습니다.
6. Sleep (), suspend () 와wait () 사이에는 어떤 차이가 있습니까?
Thread.sleep() 는 현재 스레드를 지정된 시간에 비실행(Not Runnable) 상태로 만듭니다.라인은 줄곧 대상의 모니터를 가지고 있다.예를 들어 하나의 스레드가 현재 하나의 동기화 블록이나 동기화 방법에 있고, 다른 스레드는 이 블록이나 방법에 들어갈 수 없다.만약 다른 라인이interrupt () 방법을 호출한다면, 그것은 그'수면의'라인을 깨울 것이다.
주의:sleep () 는 정적 방법입니다.이것은 현재 라인에만 유효하다는 것을 의미한다. 흔히 볼 수 있는 오류는 t.sleep () 를 호출하는 것이다. (여기 t는 현재 라인과 다른 라인이다.)t.sleep () 를 실행하더라도 현재 라인이 수면에 들어가는 것이지 t 라인이 아닙니다.t.suspend () 는 유행이 지난 방법으로 suspend () 를 사용하여 라인이 정체 상태에 들어간다. 이 라인은 대상의 모니터를 가지고 있기 때문에 suspend () 는 자물쇠 문제를 일으키기 쉽다.
object.wait () 는 현재 라인을 "실행 불가능"상태에서 만듭니다. sleep () 와 다른 것은wait는object의 방법이지 thread가 아닙니다.object를 호출합니다.wait () 시, 라인은 먼저 이 대상의 대상 자물쇠를 가져와야 합니다. 현재 라인은 자물쇠 대상에서 동기화를 유지해야 합니다. 현재 라인을 대기 대기열에 추가한 다음 다른 라인은 같은 대상 자물쇠를 동기화하여object를 호출할 수 있습니다.notify (), 이렇게 하면 원래 대기 중인 라인을 깨우고 자물쇠를 놓습니다.기본적으로wait ()/notify () 는sleep ()/interrupt () 와 유사하지만, 전자는 대상 자물쇠를 가져와야 합니다.
7. 정적 방법에서 동기화를 사용할 때 어떤 일이 발생합니까?
동기화 정적 방법은 이 종류의'Class'대상을 얻을 수 있기 때문에 한 라인이 동기화 정적 방법에 들어갈 때 라인 모니터는 클래스 자체의 대상 자물쇠를 가져오고 다른 라인은 이 종류의 정적 동기화 방법에 들어갈 수 없습니다.그것은 실례 방법과 같지 않다. 왜냐하면 여러 개의 라인이 서로 다른 실례 동기화 실례 방법에 동시에 접근할 수 있기 때문이다.
8. 동기화 방법이 실행되었을 때 라인에서 대상의 비동기화 실례 방법을 호출할 수 있습니까?
네, 비동기화 방법은 아무 문제 없이 항상 호출될 수 있습니다.실제로 자바는 비동기화 방법에 대해 어떤 검사도 하지 않았고 잠금 대상은 동기화 방법이나 동기화 코드 블록에서만 검사했다.만약 하나의 방법이 동기화라고 성명되지 않았다면, 공유 데이터 자바를 사용하더라도 여전히 호출될 것이고, 안전 여부를 검사하지 않을 것이기 때문에 이런 상황에서 특히 조심해야 한다.하나의 방법이 동기화인지 아닌지는 임계구 접근 (critial sectionaccess) 에 달려 있으며, 만약 방법이 임계구 (공유 자원이나 데이터 구조) 에 접근하지 않는다면 동기화라고 성명할 필요가 없다.
다음은 예시 설명이 있습니다. Common 클래스는 두 가지 방법으로synchronizedMethod1()과method1()이 있습니다. MyThread 클래스는 독립된 라인에서 이 두 가지 방법을 호출합니다.

public class Common { 
    public synchronized void synchronizedMethod1() { 
      System.out.println("synchronizedMethod1 called"); 
      try { 
        Thread.sleep(1000); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
      System.out.println("synchronizedMethod1 done"); 
    } 
 
    public void method1() { 
      System.out.println("Method 1 called"); 
      try { 
        Thread.sleep(1000); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
      System.out.println("Method 1 done"); 
    } 
  } 

public class MyThread extends Thread { 
    private int id = 0; 
    private Common common; 
 
    public MyThread(String name, int no, Common object) { 
      super(name); 
      common = object; 
      id = no; 
    } 
 
    public void run() { 
      System.out.println("Running Thread" + this.getName()); 
      try { 
        if (id == 0) { 
          common.synchronizedMethod1(); 
        } else { 
          common.method1(); 
        } 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
    } 
 
    public static void main(String[] args) { 
      Common c = new Common(); 
      MyThread t1 = new MyThread("MyThread-1", 0, c); 
      MyThread t2 = new MyThread("MyThread-2", 1, c); 
      t1.start(); 
      t2.start(); 
    } 
  } 

이것은 프로그램의 출력입니다.
Running ThreadMyThread-1
synchronizedMethod1 called
Running ThreadMyThread-2
Method 1 called
synchronizedMethod1 done
Method 1 done
그 결과synchronizedMethod1 () 방법이 실행되더라도method1 () 은 호출됩니다.
9. 한 대상의 두 라인에서 두 개의 다른 동기화 실례 방법을 사용할 수 있습니까?
아니오, 하나의 대상이 실례 방법을 동기화했기 때문에, 라인은 대상의 대상 자물쇠를 얻었습니다.따라서 이 방법을 실행하고 대상의 자물쇠를 풀어야만 다른 동기화 방법을 실행할 수 있다.다음 코드 예시를 보면 매우 명확합니다. Common 클래스는synchronizedMethod1()과synchronizedMethod2() 방법이 있습니다. MyThread는 이 두 가지 방법을 호출합니다.

public class Common { 
    public synchronized void synchronizedMethod1() { 
      System.out.println("synchronizedMethod1 called"); 
      try { 
        Thread.sleep(1000); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
      System.out.println("synchronizedMethod1 done"); 
    } 
 
    public synchronized void synchronizedMethod2() { 
      System.out.println("synchronizedMethod2 called"); 
      try { 
        Thread.sleep(1000); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
      System.out.println("synchronizedMethod2 done"); 
    } 
  } 

public class MyThread extends Thread { 
 private int id = 0; 
 private Common common; 
 
 public MyThread(String name, int no, Common object) { 
  super(name); 
  common = object; 
  id = no; 
 } 
 
 public void run() { 
  System.out.println("Running Thread" + this.getName()); 
  try { 
  if (id == 0) { 
   common.synchronizedMethod1(); 
  } else { 
   common.synchronizedMethod2(); 
  } 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
 } 
 
 public static void main(String[] args) { 
  Common c = new Common(); 
  MyThread t1 = new MyThread("MyThread-1", 0, c); 
  MyThread t2 = new MyThread("MyThread-2", 1, c); 
  t1.start(); 
  t2.start(); 
 } 
 } 

10. 자물쇠가 무엇입니까
사쇄는 두 개 또는 두 개 이상의 라인이 무한히 막히고 라인 간에 서로 기다리는 데 필요한 자원이다.이러한 상황은 두 라인이 다른 자원의 자물쇠를 가져오려고 시도할 때, 모든 라인은 사용자 프로세스가 종료되지 않는 한 다른 자원 자물쇠의 방출을 무한히 기다리는 데 빠질 수 있다.JavaAPI의 경우 스레드 잠금이 일시적으로 발생할 수 있습니다.
  • 두 라인이 서로 Thread를 호출할 때.join ()
  • 두 라인이 끼워 넣은 동기화 블록을 사용하면 한 라인이 다른 라인에 필요한 자물쇠를 차지하고 서로 기다릴 때 막히면 자물쇠가 사라질 수 있다..
  • 11. 무엇이 라인 굶어 죽고, 무엇이 자물쇠입니까?
    루틴 아사와 활자물쇠는 사쇄와 같은 흔한 문제가 되고 싶지 않지만 병발 프로그래밍 디자이너에게는 해후와 같다.
    모든 스레드가 막히거나 필요한 자원이 잘못되어 처리할 수 없으며, 비차단 스레드가 존재하지 않아 자원을 사용할 수 있습니다.JavaAPI에서 스레드 잠금은 다음과 같은 경우에 발생할 수 있습니다.
  • 모든 스레드가 프로그램에서 Object를 실행합니다.wait(0), 매개 변수가 0인 wait 방법.프로그램은 해당 대상에 Object가 호출될 때까지 생활 자물쇠를 보냅니다.notify () 또는 Object.notifyAll ().
  • 모든 스레드가 무한 순환 중..
  • 이곳의 문제는 상세하지 않으니 여러분에게 도움이 되었으면 합니다. 만약 여러분이 궁금한 것이 있으면 저에게 메시지를 남겨 주십시오. 편집자는 제때에 여러분에게 회답할 것입니다.여기에서도 저희 사이트에 대한 지지에 감사드립니다!

    좋은 웹페이지 즐겨찾기