"안녕하세요, 아미고! 어제 우리는 멀티스레딩의 장점과 편리함에 대해 논의했습니다. 이제 단점을 살펴볼 차례입니다. 그리고 불행히도 그것들은 작지 않습니다."

이전에 우리는 프로그램을 서로의 메서드를 호출하는 개체 집합으로 보았습니다. 이제 모든 것이 조금 더 복잡해집니다. 프로그램은 여러 개의 "작은 로봇"(스레드)이 크롤링하고 메서드에 포함된 명령을 실행하는 개체 집합과 비슷합니다.

이 새로운 해석은 첫 번째 해석을 취소하지 않습니다. 그들은 여전히 ​​객체이고 여전히 서로의 메서드를 호출합니다. 그러나 우리는 여러 스레드가 있고 각 스레드는 자체 작업 또는 작업을 수행한다는 점을 기억해야 합니다.

프로그램이 점점 복잡해지고 있습니다. 다른 스레드는 수행하는 작업에 따라 다른 개체의 상태를 변경합니다. 그리고 그들은 서로의 발가락을 밟을 수 있습니다.

그러나 최악의 상황은 Java 시스템 내부에서 발생합니다. 이미 말했듯이 스레드의 명백한 동시성은 프로세서가 한 스레드에서 다른 스레드로 지속적으로 전환한다는 사실에 의해 달성됩니다. 스레드로 전환하고, 10밀리초 동안 작동하고, 다음 스레드로 전환하고, 10밀리초 동안 작동하는 식입니다. 그리고 여기에 문제가 있습니다. 이러한 스위치는 가장 부적절한 순간에 발생할 수 있습니다. 다음 예를 고려하십시오.

첫 번째 스레드의 코드 두 번째 스레드의 코드
System.out.print ("Nick is");
System.out.print ("");
System.out.print ("15");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
System.out.print ("Lena is");
System.out.print ("");
System.out.print ("21");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
표시될 것으로 예상되는 것
닉은 15세
레나는 21세
실제 코드 실행 첫 번째 스레드의 코드 두 번째 스레드의 코드
System.out.print ("Nick is");
System.out.print ("Lena is");
System.out.print (" ");
System.out.print (" ");
System.out.print ("15");
System.out.print ("21");
System.out.print (" ");
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
System.out.print ("years old");
System.out.println ();
System.out.print ("Nick is");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("15");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
//other thread is running
//other thread is running
//other thread is running
System.out.print ("Lena is");
System.out.print (" ");
//other thread is running
//other thread is running
System.out.print ("21");
System.out.print (" ");
//other thread is running
//other thread is running
//other thread is running
System.out.print ("years old");
System.out.println ();
실제로 표시되는 것
닉은  레나가   15  21  

그리고 여기 또 다른 예가 있습니다:

암호 설명
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
스왑 방법은 및 변수 swap의 값입니다 .name1name2

동시에 두 스레드에서 호출되면 어떻게 될까요?

실제 코드 실행 첫 번째 스레드의 코드 두 번째 스레드의 코드
String s1 = name1; //Ally
name1 = name2; //Lena
String s2 = name1; //Lena(!)
name1 = name2; //Lena
name2 = s1; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s1;
//other thread is running
//other thread is running
//other thread is running
String s2 = name1;
name1 = name2;
//other thread is running
name2 = s2;
결론
두 변수 모두 «Lena» 값을 갖습니다.
«Ally» 개체가 성공하지 못했습니다. 잃어버렸습니다.

"이렇게 간단한 대입 연산으로 이런 오류가 발생할 줄 누가 짐작이나 했겠습니까!"

"예, 이 문제에는 해결책이 있습니다. 하지만 이것에 대해서는 나중에 이야기하겠습니다. 목이 건조합니다."