방법 1) Thread 클래스를 상속
class MyThread extends Thread {
public void run() { //run() 메소드 오버라이딩
this.work();
}
public void work() {
for (int i=o; i<100; i++){
System.out.println("Thread로 만든 " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
방법 2) Runnable 인터페이스 사용
class MyRunnable implements Runnable {
public void run() {
this.work()
}
public void work() {
for (int i=0; i<100; i++){
System.out.println("Runnable로 만든 " + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
방법 3) 익명 클래스 사용
Thread t3 = new Thread(
new Runnable() {
public void run() {
System.out.println("익명 클래스로 만든 " + i);
}
}
);
t3.start();
방법 4) 람다식 사용
Thread t4 = new Thread(()->{
System.out.println("람다식으로 만든 " + i);
});
t4.start();
람다식 : 불필요한 선언 지우고 핵심 로직만 남기기
( ) : 매개변수 없음 -> { } : 중괄호 안의 내용 실행
Runnable() -> run() 메소드 하나라서 생략 가능



//Thread 상속받은 Player1

//Runnable로 구현된 Player2

Player1에 의해 생성된 p1, p2, p3과 Player2에 의해 생성된 t1, t2, t3의 속도
=> 출력할 때마다 순서 달라짐!! start( )가 호출된 순서대로 출력되지 않음

안전성 문제로 stop( )은 사용 안함!! -> 대신 break, return, interrupt( ) 신호 사용

main에서 car2에 interrupt 신호 보냄 -> 스포츠카: interrupt 발생
goal을 설정한 후 goal까지 달리기, 중간에 interrupt 신호 감지하면 쓰레드 종료
++
랜덤하게 설정한 내용과 interrupt 신호 감지에 대한 내용을 잘 이해할 수 있어야할듯,,,,,
synchronized : 메소드 전체 혹은 코드 블록에 지정하여 한번에 하나의 쓰레드만이 공유 데이터에 접근할 수 있도록 제어


기존의 lab#5의 User을 수정하여 두 명의 user을 설정하여 한 명은 desposit만, 한 명은 withdraw만 실행하도록 함

deposit과 withdraw 모두 동기화처리해서
한 계좌에 여러 쓰레드가 동시에 호출할 수는 있지만 처리는 한번에 하나씩 되도록 함 -> 하나의 쓰레드가 공유 데이터를 사용하면 다른 쓰레드는 사용하지 못하게 함

join( ) : 다른 쓰레드 실행 대기
?? // throws InterruptedException 이거 이해 필요함,,,,,,


join( ) 사용해서 모든 쓰레드가 완료될 때까지 대기
join( ), wait( ), notify( ) ... 동기화처리 필요
sleep( ) : 일정 시간동안 쓰레드 일시정지
wait( ) : 다른 쓰레드의 신호를 기다리며 일시중지

Prince와 Princess 클래스에서 각각 lock 변수 선언
synchronized(lock)을 통해 동기화
wait( )와 notify( )는 synchronized(lock) 블록 안에 있어야 함 -> lock을 가지고 있는 동안에만 실행!
Princess )
1. synchronized(lock)
2. lock.wait( ) -> 열쇠 놓고 쓰레드 정지
Prince )
1. synchronized(lock) : princess가 놓은 열쇠 잡음
2. lock.notify( ) -> princess 깨움

synchronized가 get( )과 put( ) 메소드 자체에 붙어 있음
-> Buffer 객체 자체가 lock의 역할을 함
empty가 true라면 wait( )를 호출하고 잠듬 -> notifyAll( ) 신호를 받고 깨어났을 때, 순간적으로 다른 쓰레드가 먼저 채가서 다시 상태가 변했을 수도 있음 -> 조건 재확인!!
notifyAll( ) -> 모든 생산자와 소비자를 깨우며 조건을 다시 확인하고, 프로그램이 계속 실행되도록 함
Buffer은 wait( )로 쓰레드를 멈추게 하고, notifyAll( )로 다시 깨우면서
생산자와 소비자가 서로 박자를 맞추게 유도 => 케이크가 없는데 소비하려고 하거나 있는데 또 생산하려고 하는 일들을 막을 수 있음

++ 동기화와 구체적인 상태 제어 더 잘 쓸 수 있도록,,