본문 바로가기

Java/본격 Java 스레드

[Java] synchronized thread 실습

신문 기자와 독자가 존재하고 기자가 기사를 쓰면 독자가 신문기사를 읽을 수 있게 한다.

각각 클래스에 thread를 상속받아 기사를 받자마자 읽을 수 있게 한다.

.

.

class NewsPaper{
	String todayNews;
	public void setTodayNews(String news){ todayNews = news; }
	public String getTodayNews() { return todayNews; }
}

class NewsWriter extends Thread{
	NewsPaper paper;
	public NewsWriter(NewsPaper paper){ this.paper = paper; }
	public void run(){ paper.setTodayNews("오늘 덥다."); }
}

class NewsReader extends Thread{
	NewsPaper paper;
	public NewsReader(NewsPaper paper){ this.paper = paper; }
	public void run(){ 
	System.out.println("오늘의 뉴스 : " + paper.getTodayNews());
	}
}
class NewsPaperSyncError{
	public static void main(String[] args) {
		NewsPaper paper = new NewsPaper();
		NewsReader reader = new NewsReader(paper);
		NewsWriter writer = new NewsWriter(paper);

		reader.start();
		writer.start();

		try{
			reader.join(); writer.join();
		}catch (InterruptedException e){
			e.printStackTrace();
		}
	}
}

.

.

하지만 실행하게되면 오늘의 뉴스에 기사가 잘 들어오다가도 null값이 들어오기도 한다.

이때 sychronized을 이용한다.

.

.

class NewsPaper{
	String todayNews;
	boolean isTodayNews = false;
	// todayNews에 값이 들어있는지 여부를 저장하는 변수

	public void setTodayNews(String news){ 
		todayNews = news;
		isTodayNews = true;
		synchronized(this){ notifyAll(); }
		// notifyAll() : wait()하고 있는 모든 스레드들을 다시 동작시킴
		}

	public String getTodayNews() { 
		if (!isTodayNews) // todaynews에 값이 없을 경우
		{
			try{
				synchronized(this){ wait(); }
				// wait() : 스레드의 동작을 멈춤(notify()로 깨울 때 까지)
			}
			catch (InterruptedException e){
				e.printStackTrace();
			}
		}
		return todayNews; }
}

class NewsWriter extends Thread{
	NewsPaper paper;
	public NewsWriter(NewsPaper paper){ this.paper = paper; }
	public void run(){ paper.setTodayNews("오늘 덥다."); }
}

class NewsReader extends Thread{
	NewsPaper paper;
	public NewsReader(NewsPaper paper){ this.paper = paper; }
	public void run(){ 
	System.out.println("오늘의 뉴스 : " + paper.getTodayNews());
	}
}
class NewsPaperSyncSuccess{
	public static void main(String[] args) {
		NewsPaper paper = new NewsPaper();
		NewsReader reader1 = new NewsReader(paper);
		NewsReader reader2 = new NewsReader(paper);
		NewsWriter writer = new NewsWriter(paper);

		try{
			reader1.start();
			reader2.start();
			Thread.sleep(1000);
			writer.start();

			reader1.join();
			reader2.join();
			writer.join();
		}catch (InterruptedException e){
			e.printStackTrace();
		}
	}
}

.

.

synchronized를 실행하면서 다른 스레드가 실행되기전에 기다려준다.

덧붙여서 notifyAll()을 사용하여 wait()하고 있는 모든 스레드들을 다시 동작시킵니다.

728x90
반응형