JAVA-Basic

10.Thread와 동기화(synchronized)

Jungsoomin :) 2020. 7. 10. 16:51

Thread-safe하지 못하다는 말을 많이 듣게 되는데, 이 부분은 뜬구름 잡듯 잘 감이 잡히지 않고 코드를 짤때 Thread-safe하지 않겠구나 하고 예측만을 하게된다.

 

일단 Thread의 실행 방법은 Thread의 매개값인 Runnable 인터페이스의 구현객체, Thread의 상속 개체 사용의 2가지가 존재하고, .start()메서드로 시작한다.

 

Runnable의 구현방식.

public class BeepTask implements Runnable {
		@Override
		public void run() {
			Toolkit toolkit = Toolkit.getDefaultToolkit();
			
			for(int i =0; i<5; i++) {
				toolkit.beep();
				System.out.println("ding");
				try{
					//Thread를 잠시 재운다.
					Thread.sleep(500);
				}catch(InterruptedException e){
					e.getStackTrace();
				}
			}
		}
}

 

Thread클래스를 상속하기.

public class MyThread extends Thread{
	//쓰레드를 상속받아 사용할 수도 있다.
	@Override
	public void run() {
		for(int i=0; i<1000; i++) {
			System.out.println("myThread : "+i);
		}
	}
}

 

실행, Thread 상속객체는 그냥 start 시켜주면 된다.

public class BeepPrintExample2 {
 public static void main(String[] args) {
	Runnable beepTask = new BeepTask();
	Thread thread = new Thread(beepTask);
	thread.start();
	
	for(int i =0; i<5; i++) {
		System.out.println("띵");
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
}

 

 

Thread-safe하려면 동기화(synchronized)처리가 되어있어야하는데, 이는 하나의 쓰레드가 synchronized블록을 넘어가기 전까지는 다른 쓰레드는 접근 할 수 없다는 것이 된다.

public class MyThread2 implements Runnable{
	//쓰레드 사용시에는 필드선언을 하지 않는다. 모든 쓰레드 객체가 공유하게되어 값이 손실된다.
	public int i =0;
	
@Override
public void run() {
	int k =0;
	synchronized(this) {
		for(int i=0; i<10000; i++) {
			this.i++;
			k++;
	}
	/*int k =0;
	for(int i=0; i<10000; i++) {
		this.i++;
		k++;*/
//		System.out.println(Thread.currentThread().getName()+" : "+i);
	}
	System.out.println(k);
}
}

 

Main 메서드

public class ThreadEx3 {
	public static void main(String[] args) throws InterruptedException{
		MyThread2 r = new MyThread2();
		Thread t= new Thread(r);
		Thread t2 = new Thread(r);
		//2개의 인스턴스에 돌게되면 값 변경이 일어날까.
		
		t.start();
		t2.start();
		
		
		t.join();
		t2.join();
		
		System.out.println(r.i);
	}
}

주석부분과 synchronized블록을 번갈아서 확인해보면, synchronized처리를 이해하기 쉬울 듯 하다.