[AVA][快速キャンパス]Threadを実施


Threadとは?

  • Process
    -実行中のプログラム
    -オペレーティングシステムからメモリを割り当てる
  • Thread
    -プログラム実行タスクの最小単位
    -1つのプロセスに1つ以上のThreadがある
  • Threadの実装

  • Java Threadクラスから継承して実装
  • 実行可能インタフェース実装
  • class MyThread implements Runnable{
    //	방법2. implements Runnable하는 법
    	@Override
    	public void run() {
    		int i;
    		for(i=0;i<=200;i++) {
    			System.out.print(i+"\t");
    			try {
    				Thread.sleep(10);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    // 방법1. extends Thread하는 법
    //	public void run() {
    //		int i;
    //		for(i=0;i<=200;i++) {
    //			System.out.print(i+"\t");
    //			try {
    //				sleep(10);
    //			} catch (InterruptedException e) {
    //				e.printStackTrace();
    //			}
    //		}
    //	}
    }
    
    
    
    
    
    public class ThreadTest {
    
    	public static void main(String[] args) {
    		//스레드는 총 3개로 메인스레드 start,end먼저 실행하고 첫번째스레드,두번째스레드 실행함
    		System.out.println("start");
    //		MyThread th1=new MyThread();
    //		MyThread th2=new MyThread();
    //		th1.start();
    //		th2.start();
    		MyThread runner1=new MyThread();
    		Thread th1=new Thread(runner1);
    		th1.start();
    		
    		MyThread runner2=new MyThread();
    		Thread th2=new Thread(runner2);
    		th2.start();
    		
    		System.out.println("end");
    		
    	}
    }

    マルチスレッドプログラミング

  • 複数のThreadのプログラム設計
  • を同時に実行することができる.
  • Threadは、それぞれのワークスペース(コンテキスト)
  • を有する.
  • 共有リソースがある場合、競合
  • が発生します.
  • キーの同期が必要
  • Threadを利用した多様な方法

  • 非運転状態CPU
  • を占有することはできない.
  • スレッドがCPUを占有できない状態を実行不可
  • と呼ぶ.
  • (sleep、wait、join)の3つの方法で実行できません
  • は実行可能な状態を返します.sleepはタイムアウト後に戻り、waitはnotifyメソッドまたはnotifyallメソッド呼び出し時に戻り、joinは他のスレッド終了時に
  • に戻ります.
  • は実行可能状態に戻ることができず、緊急状態のスレッドは中断したセッションを発行すると異常処理されます.
  • Thread優先度

  • 直接運転すると、NORMAL PRORITY 5がある
  • join()メソッド


    他のThreadの結果を表示および実行する必要がある場合は、join()メソッドを使用します.
  • join()メソッドを呼び出すスレッドはnon-runnable状態になります
  • public class JoinTest extends Thread{
    	
    	int start;
    	int end;
    	int total;
    	
    	public JoinTest(int start, int end) {
    		this.start=start;
    		this.end=end;
    	}
    	
    	public void run() {
    		int i;
    		for(i=start;i<=end;i++) {
    			total += i;
    		}
    	}
    	
    	public static void main(String[] args) {
    		JoinTest jt1=new JoinTest(1, 50);
    		JoinTest jt2=new JoinTest(51, 100);
    		
    		jt1.start();
    		jt2.start();
    		
    		try {
    			jt1.join();
    			jt2.join();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    		int total=jt1.total+jt2.total;
    		System.out.println("jt1.total = "+ jt1.total);
    		System.out.println("jt2.total = "+ jt2.total);
    		
    		System.out.println(total);
    	}
    
    }

    わりこみほうしき

  • 送信が中断し、他のスレッドに異常が発生する
  • .
  • スレッドがjoin()、sleep()およびwait()メソッドによってブロックされる場合、
  • を中断することによって再実行することができる.
    public class InterruptTest extends Thread{
    	
    	public void run() {
    		int i;
    		for(i=0;i<100;i++) {
    			System.out.println(i);
    		}
    		try {
    			sleep(5000);
    		} catch (InterruptedException e) {
    			System.out.println(e);
    			System.out.println("Wake!!!");
    		}
    	}
    	public static void main(String[] args) {
    		
    		InterruptTest test= new InterruptTest();
    		test.start();
    		test.interrupt();
    		
    		System.out.println("end");
    	}
    
    }

    終了


    run()メソッドのwhile文を使用して、
  • デーモンプロセスなどの無限に繰り返されるスレッドを終了することができます.
  • Thread.stop()を使用しない
  • public class TerminateThread extends Thread{
    
    	private boolean flag=false;
    	int i;
    	
    	public TerminateThread(String name) {
    		super(name);
    	}
    	
    	public void run() {
    		while(!flag) {
    			try {
    				sleep(100);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		System.out.println(getName()+"end");
    	}
    	
    	public void setFlag(boolean flag) {
    		this.flag=flag;
    	}
    	
    	public static void main(String[] args) throws IOException {
    		TerminateThread threadA=new TerminateThread("A");
    		TerminateThread threadB=new TerminateThread("B");
    		
    		threadA.start();
    		threadB.start();
    		
    		int in;
    		while(true) {
    			in=System.in.read();
    			if(in == 'A') {
    				threadA.setFlag(true);
    			}
    			else if(in == 'B') {
    				threadB.setFlag(true);
    			}else if( in == 'M') {
    				threadA.setFlag(true);
    				threadB.setFlag(true);
    				break;
    			}
    //			else {
    //				System.out.println("try again");
    //			}
    		}
    		System.out.println("main end");
    	}
    
    }

    りんかいいき


    リソース
  • は、2つ以上のスレッド
  • に同時にアクセスすることができる.
    スレッドが
  • の重要な部分と同時にアクセスする場合、実行結果
  • は保証されません.
  • スレッド間の同期(同期)
  • が必要

    同期(synchronization)


    複数のスレッドが
  • 臨界領域にアクセスする場合、1つのスレッド実行中に共有リソースをロックして、他のスレッドが
  • にアクセスすることを阻止する.
  • の同期を誤って実施すると、デッドロックが発生する可能性があります.
  • Javaでの同期化

  • 同期文と同期方法
  • を使用
  • 同期文
    synchronized(参照式){}
    参照式のオブジェクトをロックする
  • 同期方法
    -現在のメソッドが属するオブジェクトをロックします.
    -synchronizedメソッド内で他のsynchronizedメソッドを呼び出さない.(デッドロック防止)
  • モード同期メソッド
    
    class Bank{
    	private int money=10000;
    	
    	//saveMoney가 수행되는 동안 다른쓰레드가  Bank에 접근못하게함
    	//Park이 실행되는 동안 ParkWife는 접근못함
    	public synchronized void saveMoney(int save) {
    		int m=this.getMoney();
    		
    		try {
    			Thread.sleep(3000);
    		}catch(InterruptedException e){
    			e.printStackTrace(); 
    		}
    		
    		setMoney(m+save);
    	}
    	
    	public synchronized void minusMoney(int minus) {
    		int m=this.getMoney();
    		
    		try {
    			Thread.sleep(200);
    		}catch(InterruptedException e){
    			e.printStackTrace(); 
    		}
    		
    		setMoney(m-minus);
    	}
    
    	public int getMoney() {
    		return money;
    	}
    
    	public void setMoney(int money) {
    		this.money = money;
    	}
    }
    
    class Park extends Thread{
    	public void run() {
    		System.out.println("start save");
    		SyncTest.myBank.saveMoney(3000);
    		System.out.println("start money : "+ SyncTest.myBank.getMoney());
    	}
    }
    
    class ParkWife extends Thread{
    	public void run() {
    		System.out.println("start minus");
    		SyncTest.myBank.minusMoney(1000);
    		System.out.println("start money : "+ SyncTest.myBank.getMoney());
    	}
    }
    
    public class SyncTest {
    
    	public static Bank myBank= new Bank();
    	
    	public static void main(String[] args) throws InterruptedException {
    		
    		Park p= new Park();
    		p.start();
    		
    		Thread.sleep(200);
    		ParkWife pw=new ParkWife();
    		pw.start();
    	}
    	
    }
    モードどうきブロック
    
    class Bank{
    	private int money=10000;
    	
    	//saveMoney가 수행되는 동안 다른쓰레드가  Bank에 접근못하게함
    	//Park이 실행되는 동안 ParkWife는 접근못함
    	public synchronized void saveMoney(int save) {
    		synchronized (this) {
    			
    			int m=this.getMoney();
    			
    			try {
    				Thread.sleep(3000);
    			}catch(InterruptedException e){
    				e.printStackTrace(); 
    			}
    			
    			setMoney(m+save);
    			
    		}
    	}
    	
     //생략
  • スレッドに同期を適用する場合はrun()を同期できません.runメソッドでsynchronizedをブロックするだけです.
  • class Bank{
    	private int money=10000;
    	
    	//saveMoney가 수행되는 동안 다른쓰레드가  Bank에 접근못하게함
    	//Park이 실행되는 동안 ParkWife는 접근못함
    	public void saveMoney(int save) {
    			
    			int m=this.getMoney();
    			
    			try {
    				Thread.sleep(3000);
    			}catch(InterruptedException e){
    				e.printStackTrace(); 
    			}
    			
    			setMoney(m+save);
    
    	}
    	
    	public void minusMoney(int minus) {
    		int m=this.getMoney();
    		
    		try {
    			Thread.sleep(200);
    		}catch(InterruptedException e){
    			e.printStackTrace(); 
    		}
    		
    		setMoney(m-minus);
    	}
    
    	public int getMoney() {
    		return money;
    	}
    
    	public void setMoney(int money) {
    		this.money = money;
    	}
    }
    
    class Park extends Thread{
    	public void run() {
    		synchronized (SyncTest.myBank) {
    			System.out.println("start save");
    			SyncTest.myBank.saveMoney(3000);
    			System.out.println("start money : "+ SyncTest.myBank.getMoney());
    		}
    		
    	}
    }
    
    class ParkWife extends Thread{
    	public void run() {
    		synchronized (SyncTest.myBank) {
    			System.out.println("start minus");
    			SyncTest.myBank.minusMoney(1000);
    			System.out.println("start money : "+ SyncTest.myBank.getMoney());
    		}
    		
    	}
    }
    
    public class SyncTest {
    
    	public static Bank myBank= new Bank();
    	
    	public static void main(String[] args) throws InterruptedException {
    		
    		Park p= new Park();
    		p.start();
    		
    		Thread.sleep(200);
    		ParkWife pw=new ParkWife();
    		pw.start();
    	}
    	
    }

    deadlock



    wait()/notify()

  • wait():リソースが有効でない場合、スレッドをnon-runnable状態に変換し、wait()状態のスレッドはnotify()呼び出しを待つ.
  • notify():待機中()のスレッドの1つをrunnableスレッド
  • として起動します.
  • notifyAll()
    -待機中のすべてのスレッドをrunnable状態にする
    -notify()ではなくnotify All()を使用することを推奨します.
    -スレッドの受信通知を制御できないため、すべてのスレッドを起動してschedulerにCPUを割り当てるとより公平になります.
  • class FastLibrary{
    	public ArrayList<String> books=new ArrayList<String>();
    	
    	public FastLibrary() {
    		books.add("태백산맥 1");
    		books.add("태백산맥 2");
    		books.add("태백산맥 3");
    
    		
    	}
    	public synchronized String lendBook() throws InterruptedException {
    		Thread t=Thread.currentThread();
    		//책이 없으면 못빌리는 것으로 if문 null처리
    		//if(books.size() == 0) return null;
    		
    		if(books.size() ==0) {
    			System.out.println(t.getName() + "wating start");
    			wait();
    			System.out.println(t.getName() + "wating end");
    		}
    		
    		
    		String title=books.remove(0);
    		System.out.println(t.getName()+ ":" + title + " lend");
    		return title;
    	}
    	
    	public synchronized void returnBook(String title) {
    		Thread t=Thread.currentThread();
    		books.add(title);
    		notify();
    		System.out.println(t.getName()+ ":" + title + " return");
    	}
    }
    
    class Student extends Thread{
    	public void run() {
    		
    		try {
    			String title=LibraryMain.library.lendBook();
    			if ( title == null) return;
    			sleep(5000);
    			LibraryMain.library.returnBook(title);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    
    public class LibraryMain {
    
    	public static FastLibrary library=new FastLibrary();
    	public static void main(String[] args) {
    		
    		Student std1=new Student();
    		Student std2=new Student();
    		Student std3=new Student();
    		Student std4=new Student();
    		Student std5=new Student();
    		Student std6=new Student();
    		
    		std1.start();
    		std2.start();
    		std3.start();
    		std4.start();
    		std5.start();
    		std6.start();
    	}
    }