読みながら【7】---javaマルチスレッド実戦【Thread/Executors】


前の2ヶ月はずっと忙しくて、しかしやはりiteyeの上で招待状を出すことを忘れないで、文章を書きます.ついに今週overは2セットのシステムをオーバーして、残りの時間は基本的に修正してメンテナンスしました.
完了した一連の「アプリケーションインストールシステム」の後、マルチスレッドに対する理解はさらに深まった.
ここに書いて、一つはみんなと分かち合い、二つは壇の中の大牛たちに教えてもらい、多くの不足点がある.
ps:『maven実戦』を見ていると寝たくなるのに、なぜか?私は普通本を読むのがまじめです.
ok.需要を見てみましょう:まずマルチスレッドを実現します.簡単に言えば、一つの方法で6つのことを完成させ、6つのことは直接関係がありません.一つのことが完成しないからといって、次のことが完成できないことはありません.すべて完了したら、次の方法を実行します.
スレッドの2つの実装方法は、コードが他のクラスを継承している場合は、Runnable言い訳を実装します.この2つの方法のスレッドには戻り値がありません.
会社のコードは貼りにくいです.ここに変相のdemoを貼ります.
ポリシー1:

public class TestThread {
	//
	private static int i;
	//          ,          ,   
	public void get(long name) {
		try {
			Thread.sleep(name);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("-----name-----"+name);
		i++;
	}
	//     。
	public int  over(int n){
		System.out.println("---over--"+n);
		return n;
	}
	
	//    
	public void  ing (){
		final TestThread td = new TestThread();
		
		Thread tr4  = new Thread(new Runnable(){
			@Override
			public void run() {
				td.get(1500L);
			}
		});
		tr4.start();
		
		new Thread(){
			public void run (){
				td.get(500L);
			}
		}.start();
		
		
		new Thread(){
			public void run (){
				td.get(100L);
			}
		}.start();
	}
	
	public void show(){
		System.out.println("=======show()========");
	}
	

	public static void main(String[] args) {
                //  
		final TestThread ted = new TestThread();
		ted.ing();
		//       ,               。            
		Thread tt = new Thread(){
		public void run (){
			while(true){
				try {    //     100ms             
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
                                     //     3 ,     ,          ,   。。。。。
				if(i==3){
					ted.show();
					ted.over(1);
				}
				
			}
		}		
		};
		tt.setDaemon(true);
		tt.start();
		
		//ted.show();	           
		
	}
}

このようにしても要求に達するようだ.しかし、明らかな欠点がある.
第一に、スレッドが同時に実行されるには、スレッドをデーモンスレッドで実行しなければなりません.これは望ましくありません.デーモンスレッドはすぐに死んでしまいます.
やるべきことに多くの時間を費やしたり、オーバーヘッドを費やしたりすると、この方法は正しく実行されません.【
具体的な原因を知らないで、大鳥が迷津を指摘することができることを望みます.
第二に、プログラムが実行されると、各スレッドが独立して走り、デーモンスレッドは各スレッドの状態を監視するだけで、各スレッドが実行したことが成功したかどうかを取得できません.これはかなり理想的ではない.
策略二:Callable
public class HasValueThread {
	public void a(){
		Callable ca1 = 	new Callable(){
			@Override
			public Object call() throws Exception {
				System.out.println("==yes===");
				return true;
			}
			
		};
		
		Date d1 = new Date();
		System.out.println("d1"+d1.toLocaleString());
		 //ExecutorService exec = Executors.newCachedThreadPool();//      
		 ExecutorService exec = Executors.newFixedThreadPool(7);//      
		  Callable c1 = new MyCallable("A",1000); 
          Callable c2 = new MyCallable("B",5000); 
          Callable c3 = new MyCallable("c",15000); 
         Future f1 =  exec.submit(c1);
         Future f2 =  exec.submit(c2);
         Future f4 =  exec.submit(c3);
         Future f3 =  exec.submit(ca1);
         
         try {
        	 
			System.out.println(f1.get().toString()+System.currentTimeMillis());
			System.out.println(f2.get().toString()+System.currentTimeMillis());
			System.out.println(f4.get().toString()+System.currentTimeMillis());
			System.out.println(f3.get().toString()+System.currentTimeMillis());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
         exec.shutdown();
	}
	
	public static void main(String[] args) {
		new HasValueThread().a();
		
		System.out.println("------");
	}

}
class MyCallable implements Callable{ 
    private String oid; 
    private long n;
    MyCallable(String oid,long n) { 
            this.oid = oid; 
            this.n = n;
    } 

    @Override 
    public Object call() throws Exception { 
    	Date d2 = new Date();
		System.out.println("d2"+d2.toLocaleString());
    		Thread.sleep(n);
            return oid+"       "; 
    } 
} 

ポリシー2を使用するメリットは、次のとおりです.
第一に、Callableのメリットは戻り値があることです.つまり、スレッドが彼の使命を成功させたかどうか、私たちは彼の戻り結果から【
カスタム結果]に表示されます.
第二:ThreadPoolExecutor【
いくつかの関連する博文を書いて草稿箱の中に置いて発表していないで、主に間違いが多すぎることを恐れています--、笑って気前がいいです」それはスレッドプールを提供して、使用方法は通常Executors工場の方法を使って配置します.apiはこう言います.
スレッド・プールは、2つの異なる問題を解決します.各タスク・コールのオーバーヘッドを削減するため、通常、多くの非同期タスクを実行する際にパフォーマンスを向上させ、タスク・セットを実行する際に使用されるスレッドを含むリソースをバインドおよび管理する方法も提供できます.各ThreadPoolExecutorは、完了したタスク数などの基本的な統計データも維持しています.Executorで戻り値付きCallableをExecutorServiceにコミットします.戻るのはタイプのみFutrue[未来、面白い]です.さらに興味深いことに、彼はすべてのCallableが実行されてから下へ行くのを待っています.もちろんコントロールが必要です.
 //ExecutorService exec = Executors.newCachedThreadPool();//      
		 ExecutorService exec = Executors.newFixedThreadPool(7);//      

最初のnewCachedThreadPool();彼はn個のスレッドを起動してあなたの任務を完成します.彼は自動スレッド回収ができる.しかし、彼の時間は60 sです.このdemoを走ることができて、彼にsleep 70秒を譲ることができることを発見しました.この問題は長い間分からなかった.
わかりやすい分かち合いを求める」.だから私は役に立たない..newFixedThreadPool(7)パラメータでスレッド数を設定できます.
総じて言えばやはりあの2つの言叶で、1つは分かち合って、1つは教えてもらいます.ありがとう