해결된 질문
작성
·
34
0
해당 로직을 보니깐 리엔트리 락을 사용 하고 있는 것을 보여집니다.
그런데 말씀 하신 내용 처럼
T1 스레드가 "Hello"
T2 스레드가 "World"
특정 파일에 쓰기를 동시적으로 여러번 하는데
HWellorl <-- 이렇게 단어가 혼잡되어서 쓰기가 되지 않는 이유에 대해서 이해가 안가서 질문 드립니다.
1번 쓰레드가 writeData("Hello");
2번 쓰레드가 writeData("World");
이렇게 멀티스레드로 실행하게 된다면
writeData 메소드를 구현하신 내용을 보면
FileWriter writer = new FileWriter("C:/Tmp/test.txt");
이렇게 새롭게 인스턴스를 새롭게 만들어서 각각 실행하기 때문에
this.lock
해당 lock 객체를 호출 할때 각각 스레드 수준에서 ThreadSafe 한 것이 아닌가요? (제가 잘못 알고 있을 수도 있습니다! )
그러니깐 만약 이렇게
FileWriter writer = new FileWriter("C:/Tmp/test.txt");
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write("World");("Hello");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write("World");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
writer 전역 변수를 만약에 T1 쓰레드하고 T2 쓰레드가 동일하게 참조해서 사용한다면 이해가 갈텐데
선생님께서 만들어주신 코드는 지역 변수로 FileWriter 객체를 생성하고 지역 변수 내에서 소멸되기 때문에 T1, T2 하고 동시화 기법에는 동작 하지 않을 것 같아서 질문 드립니다.
답변 1
0
우선 Java에는 전역 변수가 없습니다. 대신 클래스 변수인 정적 변수가 있긴 합니다. 그리고 무엇보다 중요한 것은 클래스에 대한 참조 변수는 말 그대로 참조일 뿐 대상 인스턴스의 생존 여부와 무관합니다. 모두 다 GC가 알아서 처리하기 때문입니다. 지역 변수인 클래스 참조자가 사라진다 해서 대상 인스턴스까지 사라지는 것은 아닙니다.
그리고 질문 초기에 보이는 write() 메서드는 그 내부에서 동기화를 실시하고 있기 때문에 여러 스레드에서 동시에 write()를 호출하더라도 실제로 호출 할 수 있는 것은 한 스레드로 제한됩니다. 이 때문에 문자열이 서로 뒤섞이지 않은 것입니다. 참고하시기 바랍니다. 😄