-> polling을 통해 계속 물어본다.
-> 하지만 polling은 계속 물어본다는 점에서 비효율적이다.
내가 물어볼 것이 아니라 Thread의 일이 끝나면 알려주면 된다.
InstanceCallback은 본인 Instace를 만들면 그것을 생성자로 인자로 넘겨준다.
인스턴스는 자기 자신을 매개변수로 받았고 thread가 끝나게 도면 recieveDigest를 호출해서
Callback 한다.
runable 인터페이스를 implement해야한다.
근데 run() 메소드는 return이 없다.
그래서 return이 없는 runable 대신에 return 타입이 있는 callables를 사용한다.
메소드 이름도 call() 이다.
-> Call이 끝나야 리턴을 받을 수 있음
-> 만약 Call이 여러개가 있다고 하자
-> 만약 return값 2개를 더해야한다고 하자
-> 그럼 하나가 끝나도 하나가 끝날 때 까지 기다려야한다
-> 그래서 결과값을 futures로 받고 다른 하나가 끝나서 결과가 나올 때까지 기다린다.
스레드를 공장처럼 돌린다.
이제까지는 콘솔에 filename 뒤에 hash 값 뒤에 찍었다.
근데 이제는 filename: 을 먼저 각각 쓰레드에서 찍고
Run하면서 또 각각 해쉬값을 찍게 된다면 어느게 어떤 해쉬값인지 판단할 수 없다.
그럼 각 쓰레드에서 filename: 해쉬값을 찍을 때 다른 작업들이 system.out을 못하게 하면 된다.
따라서 작업하는 동안 resource를 독점하게 하면 된다.
synchronized (System.out) {
System.out.print(input + ": ");
System.out.print(DatatypeConverter.printHexBinary(digest));
System.out.println();
}
위처럼 하면 Thread를 돌릴 때 이 작업들이 묶인다.
public synchronized void writeEntry(String message) throws IOException { Date d = new Date();
out.write(d.toString());
out.write('\t');
out.write(message);
out.write("\r\n");
}
위처럼 메서드에도 적용가능하다.
하지만 동기화를 자주 사용하면 Deadlock과 같은 문제가 발생한다.
두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에
결과적으로 아무것도 완료되지 못하는 상태이다.
-> 밑 사람이 내려가지 않으면 아무것도 할 수 없는 상태
내가 A라는 Resource를 독점하고 있으면 B가 A를 써야하는데 사용하지 못하게 됨
-> 동기화는 가급적 쓰지 않는 것이 좋음