15일차 : 스레드의 동기화
--------------------------------------- package test01.thread; ----------------------------------------------------------
임시 저장소에 데이터를 저장하는 스레드
package test01.thread; // 임시 저장소에 데이터를 저장하는 스레드 class TempThread extends Thread{ //Message msg=new Message();==>두 개의 자원을 사용하겠다고 여기에 이렇게주면 안된다. private Message msg; //main 메소드에서 생성된 객체를 참조해 온다. public TempThread(Message msg){ this.msg=msg; } public void run(){ char[] data={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}; //다운로드 할 데이터. 이것을 msg.set~로 옮겨야 함. for(int i=0; i<data.length; i++){ //다운로드 할 데이터를 임시 저장소에 저장하기 msg.setMsg(String.valueOf(data[i])); //setMsg는 파라미터 값을 돌면서 계속 연결해주는 역할 //for(int j=0; j<=1000; j++); //시간 지연하기 } System.out.println("임시저장공간에 다운로드 완료"); } } // 임시 저장소의 데이터를 파일로 저장하는 스레드 class WriteThread extends Thread{ private Message msg; //main 메소드에서 생성된 객체를 참조해 온다. public WriteThread(Message msg){ this.msg=msg; } public void run(){ System.out.println("파일로 저장 시작!"); System.out.println(msg.getMsg()); System.out.println("파일에 저장 완료!"); } } public class MainTest { public static void main(String[] args) { Message msg=new Message();//스레드간에 공유자원이 될 객체 TempThread thread1=new TempThread(msg); WriteThread thread2=new WriteThread(msg);//msg 객체를 파일로 저장 thread1.start(); thread2.start(); } }
입금 기능을 갖는 스레드
package test01.thread; //동기화 class InputThread extends Thread{//입금 기능을 갖는 스레드 private Bank bank; public InputThread(Bank bank){ this.bank=bank; } public void run(){ synchronized (bank) { //싱크로나이즈드. (bank) =공유자원 동기화 처리하기(lock 이 걸림) System.out.println("입금 처리중"); bank.input(1000); //공유자원 for(int i=1; i<=100000000; i++);//;을 안찍어주면 계속 루프를 돌기 때문에 찍어준다. 시간지연(입금 처리중이라고 가정하자.) System.out.println("입금 완료!"); System.out.println("입금 후 잔액: " + bank.getMoney()); } } } class OutputThread extends Thread{ private Bank bank; public OutputThread(Bank bank){ this.bank=bank; } public void run(){ synchronized (bank){//동기화 처리하기(lock 이 걸림) System.out.println("출금 처리중"); bank.output(2000); for(int i=1; i<=100000000; i++);//시간지연(입금 처리중이라고 가정하자.) System.out.println("출금 완료!"); System.out.println("출금 후 잔액: "+bank.getMoney()); } } } public class MainTest01 { public static void main(String[] args) { Bank bank=new Bank(5000); new OutputThread(bank).start(); new OutputThread(bank).start(); new OutputThread(bank).start(); new InputThread(bank).start(); new OutputThread(bank).start(); new OutputThread(bank).start(); } }
공유 자원이 될 객체
package test01.thread; //공유 자원의 될 객체 public class Bank { private double money;//잔액 public Bank(double money){ this.money=money; } public void input(double m){//입금기능 money+=m; } public void output(double m){//출금기능 if(money<m){ //입금 된 돈이 적으면 System.out.println("잔액부족"); return;//메소드 끝내기 } money-=m; } public double getMoney(){ return money; } }
스레드간의 객체 공유하기
package test01.thread; // 스레드 간의 객체 공유하기 //공유 될 클래스 public class Message { private String msg=""; public void setMsg(String msg){ this.msg+=msg; } public String getMsg(){return msg;} }
--------------------------------------- package test02.thread; ----------------------------------------------------------
Test02 InputThread
package test02.thread; class InputThread extends Thread{ private Bank bank; public InputThread(Bank bank){ this.bank=bank; } public void run(){ //bank 객체 자체에서 동기화 처리가 되어있으므로 사용하는 곳에서는 동기화 처리를 하지 않는다. bank.input(1000); } } class OutputThread extends Thread{ private Bank bank; public OutputThread(Bank bank){ this.bank=bank; } public void run(){ bank.output(2000); } } public class MainTest { public static void main(String[] args) { Bank bank=new Bank(5000); new OutputThread(bank).start(); new OutputThread(bank).start(); new InputThread(bank).start(); new OutputThread(bank).start(); } }
Test02 공유자원이 될 객체
package test02.thread; //공유 자원의 될 객체 public class Bank { private double money;//잔액 public Bank(double money){ this.money=money; } public synchronized void input(double m){ //동기화 메소드 System.out.println("입금 처리중"); for(int i=1; i<=100000000; i++); money+=m; System.out.println("입금 처리 완료"); System.out.println("입금 후 잔액: " +money); } public synchronized void output(double m){ //동기화 메소드 System.out.println("출금 처리중"); for(int i=1; i<=100000000; i++); if(money<m){ //입금 된 돈이 적으면 System.out.println("잔액부족"); return;//메소드 끝내기 } money-=m; System.out.println("입금 처리 완료"); System.out.println("입금 후 잔액: " +money); } public double getMoney(){ return money; } }
--------------------------------------- package test03.thread; ----------------------------------------------------------
Test03 임시 저장 공간에 다운로드 및 파일저장
package test03.thread; class TempThread extends Thread{//템프스레드는 Message msg 객체를 가지고 있지 private Message msg; public TempThread(Message msg){ this.msg=msg; } public void run(){ synchronized (msg) { //동기화 System.out.println("임시 저장 공간에 다운로드 시작"); char[] data={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};//다운로드 할 데이터. 이것을 msg.set~로 옮겨야 함. for(int i=0; i<data.length; i++){ //다운로드 할 데이터를 임시 저장소에 저장하기 msg.setMsg(String.valueOf(data[i]));//setMsg는 파라미터 값을 돌면서 계속 연결해주는 역할 for(int j=0; j<=1000; j++);//시간 지연하기 } System.out.println("임시저장공간에 다운로드 완료"); msg.notify();//wait 하고 있는 객체를 깨운다. msg.setStatus(true); //참이면 32행이 false 로 실행하지 않고 파일 저장 시작~ 뜸 } } } // 임시 저장소의 데이터를 파일로 저장하는 스레드 class WriteThread extends Thread{ private Message msg; //main 메소드에서 생성된 객체를 참조해 온다. public WriteThread(Message msg){ this.msg=msg; } public void run(){ synchronized(msg) { if(msg.isStatus()==false){//생산자 스레드가 아직 notify 하지 않는 경우 ==> wait 가 수행되어야 함 try{ msg.wait();//다른 스레드에서 notify 메소드로 깨울 때까지 wait 상태가 됨. synchronized 블록 안에서만 사용 가능! }catch(InterruptedException ie){ System.out.println(ie.getMessage()); } } System.out.println("파일로 저장 시작!"); System.out.println(msg.getMsg()); System.out.println("파일에 저장 완료!"); } } } public class MainTest { public static void main(String[] args) { Message msg=new Message(); //스레드간에 공유자원이 될 객체 TempThread thread1=new TempThread(msg); WriteThread thread2=new WriteThread(msg);//msg 객체를 파일로 저장 thread1.start(); thread2.start(); } }
Test03 스레드 간의 객체 공유하기
package test03.thread; // 스레드 간의 객체 공유하기 // 공유될 클래스 public class Message { private String msg=""; private boolean status=false; public void setStatus(boolean status){ this.status = status; } public boolean isStatus(){ return status; } public void setMsg(String msg){ //setMsg : setter 메소드 라고 부름 this.msg+=msg; } public String getMsg(){ //getMsg : getter 메소드라고 부름 return msg; } }
--------------------------------------- package test04.thread; ----------------------------------------------------------
Test04 ThreadJoin
package test04.thread; import java.util.Random; class MyThread1 extends Thread{ public void run(){ Random rnd=new Random(); for(int i=1;i<=100;i++){ int n=rnd.nextInt(100); System.out.print("발생된난수:"+n); if(i%10==0) System.out.println(); } System.out.println("자식스레드 종료"); } } public class ThreadJoin { public static void main(String[] args) { MyThread1 thread=new MyThread1(); thread.start(); try{ thread.join(); //부모 스레드가 자식 스레드가 종료 될 때까지 기다림 }catch(InterruptedException ie){ System.out.println(ie.getMessage()); } System.out.println("메인스레드종료"); } }
Test04 hreadStop
package test04.thread; import java.util.Random; class MyThread extends Thread{ private boolean status=false; public void run(){ Random rnd=new Random(); status=true; while(status){ int n=rnd.nextInt(100); System.out.println("발생된난수:"+n); } } public void stopMyThread(){ status=false; } } public class ThreadStop { public static void main(String[] args) { MyThread th=new MyThread(); th.start();//스레드 실행하기 try{ Thread.sleep(3000); }catch(InterruptedException ie){} th.stopMyThread();//스레드 종료하기 } } // 메인 스레드에서 th.stopMyThread(); 호출
'JAVA 기초' 카테고리의 다른 글
for문 - 별찍기 (0) | 2013.05.17 |
---|---|
14일차 : 스레드(Thread) (0) | 2012.08.12 |
13일차 : IO, File클래스, 내부클래스, 객체의 직렬화, 재귀메소드 (0) | 2012.08.12 |
12일차 : IO, 입출력 (0) | 2012.08.12 |
11일차 : 예외처리, IO(InputStream,OutputStream), 패키지 만들기 (0) | 2012.08.12 |