자바

자바 스레드 동기 비동기 이해 및 활용

Unipiz 2020. 9. 18. 11:20

자바 웹소켓을 사용하여 채팅방을 관리해주는 배열을 구현하면서 동기의 필요성을 느꼈다.

예를들어, 10개의 채팅방이있다.

 

그 중 7번째 채팅방의 유저가 모두 나가서 해당 Room은 비어있다. (remove방식 X)

이제 유저1, 유저2 각각 createRoom함수를 동시에 호출하여 Room 생성 요청을 했다.

 

하나의 스레드로 Room배열을 검사했으면 아무런 문제가 없지만(동기)

유저1, 유저2의 요청에대한 스레드가 동시에 검사(비동기)를 진행하면서 7번방이 Null이라 둘 모두에게

방을 내어주려고 할 때 문제가 발생한다..

 

이제 둘 이상의 스레드가 동기적으로 실행하도록하는 방법을 알아보자.

목표1. 하나의 객체접근 시 동기 접근

 

1.비동기 

public class TestThread {
	public static void main(String[] args) {
    		//0. 객체 생성
		shareObject so = new shareObject();
        
        	//1. 스레드1 생성
		Thread t1 = new Thread(()->{
			so.call(Thread.currentThread().getName());
		});
        
        	//2. 스레드2 생성
		Thread t2 = new Thread(()->{
			so.call(Thread.currentThread().getName());
		});
        
        	//3. 작업 시작
		t1.start();
		t2.start();
	}
}

//공유할 클래스생성
class shareObject {
	public void call(String th){
		for(int i=0;i<20;i++){
			System.out.println(th+" 작업"+i);
			try {
            	Thread.sleep(100);
			} catch (InterruptedException e) {e.printStackTrace();}
		}
	}
}

t1, t2 막 치고 들어온다. 한 줄 한 줄;

 

2. 함수 동기화 --> synchronized 추가

public synchronized void call(String th){ 로 변경

한 스레드의 call함수가 끝나고 나서야 다음 스레드가가 치고 들어온다.

 

3. 블럭단위 동기 synchronized (this){}    추가

class shareObject {
	public void call(String th){
		synchronized (this){
		for(int i=0;i<20;i++){
			System.out.println(th+" 작업"+i);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {e.printStackTrace();}
		}
		}
	}
}

같은 결과 //

 

 

4. 이제 다음 코드 실행 결과는 ?

	public static void main(String[] args) {
		shareObject so = new shareObject();
		Thread t1 = new Thread(()->{
			so.call(Thread.currentThread().getName());
			so.call("1111");
			so.call("2222");
			so.call("3333");
			so.call("4444");
		});
		Thread t2 = new Thread(()->{
			so.call(Thread.currentThread().getName());
			so.call("!!!!");
			so.call("@@@@");
			so.call("####");
			so.call("$$$$");
		});
		t1.start();
		t2.start();
		}

 

위 경우 동기 단위는 10개로 나뉘어 진다.

 

한 스레드 내에서는 동기적으로 호출을 하고

t1, t2 두 스레드는 경쟁을하고

한 스레드 중 call함수를 먼저 호출 했으면 다른 스레드는 기다리게 된다.

 

 

자, 이제 멀티스레드의 list 작업 시 synchronized를 사용하여 동기적으로

잘 적용하자.

'자바' 카테고리의 다른 글

[JAVA] String에 대하여  (0) 2022.07.12
【SPRING】스프링 세션 시간 설정 위치  (0) 2020.11.05
스프링부트 로그 초간단 사용법  (0) 2020.09.17