同時(二)

5615 ワード

1:バックグラウンドスレッド(デーモンスレッド)
バックグラウンドスレッドの半分は、プログラムの不可欠な部分ではなく、汎用サービスを提供するために使用されます.すべての非バックグラウンドスレッドが終了すると、プロセスはすべてのバックグラウンドスレッドを殺します.バックグラウンドプロセスはfinallyメソッドを実行しない場合runメソッドを終了する可能性があります
public class SimpleDaemos implements Runnable {
	public static void main(String[] args) throws InterruptedException {
		for(int i=0;i<10;i++) {
			Thread daemo = new Thread(new SimpleDaemos());
			daemo.setDaemon(true);
			daemo.start();
		}
		System.out.println("All daemo started");
		TimeUnit.MILLISECONDS.sleep(175);
	}
	
	public void run() {
		try {
			while(true) {
				TimeUnit.MILLISECONDS.sleep(100);
				System.out.println(Thread.currentThread() + " " + this);
			}
		} catch (InterruptedException e) {
			System.out.println("sleep() interrupted");
		}
	}
}

 
2:ThreadFactoryカスタムスレッド属性
public class DaemonFromFactory implements Runnable{
	public static void main(String[] args) throws InterruptedException {
		// , 
		ExecutorService exe = Executors.newCachedThreadPool(new DaemoThreadFactory());
		for(int i=0;i<10;i++) {
			exe.execute(new DaemonFromFactory());
		}
		System.out.println("All daemos started");
		TimeUnit.MILLISECONDS.sleep(500);
	}
	
	public void run() {
		
	}
}

/**
 *  
 * @author zhuchangxin
 *
 */
class DaemoThreadFactory implements ThreadFactory {
	public Thread newThread(Runnable r) {
		Thread t = new Thread(r);
		t.setDaemon(true);
		return t;
	}
}

3:join()スレッドを追加
aスレッドでb.join()を呼び出します.aスレッドは、bの実行が完了するのを待ってから実行を続行する.期間中にinterrupt()メソッドを呼び出してスレッドを中断すると、bスレッドが中断され、aは下向きに実行されます.
public class Joining {
	public static void main(String[] args) throws InterruptedException {
		Sleeper sleepy = new Sleeper("Sleepy" , 1500);// 1
		Sleeper grumpy = new Sleeper("Grumpy" , 1500);// 2
		
		Joiner dopey = new Joiner("Dopey", sleepy);// 3
		Joiner doc = new Joiner("Doc", grumpy);// 4
		
		Thread.sleep(500);
		grumpy.interrupt();
	}
}

class Sleeper extends Thread {
	private int duration;
	
	public Sleeper(String name,int sleepTime) {
		super(name);
		this.duration = sleepTime;
		start();
	}
	
	public void run() {
		try {
			TimeUnit.MILLISECONDS.sleep(duration);// 5
		} catch (InterruptedException e) {
			// Thread getName 
			System.out.println(getName() + " was interrupted. isInterrupted(): " + isInterrupted());
			return ;
		}
		System.out.println(getName() + " has awakened");
	}
}

class Joiner extends Thread {
	private Sleeper sleeper;
	public Joiner(String name,Sleeper sleeper) {
		super(name);
		this.sleeper = sleeper;
		start();
	}
	
	public void run() {
		try {
			sleeper.join();
		}catch (InterruptedException e) {
			System.out.println("Interrupted");
		}
		System.out.println(getName() + " join completed");
	}
}


 :
Grumpy was interrupted. isInterrupted(): false
Doc join completed
Sleepy has awakened
Dopey join completed

4:例外の取得
スレッドから脱出した例外をキャプチャすることはできません.runメソッドを脱出すると、mainボディをtry,catchに配置してもコンソールに出力されます.
public class SimpleDaemos implements Runnable {
	public static void main(String[] args) {
		try {
			for(int i=0;i<10;i++) {
				Thread daemo = new Thread(new SimpleDaemos());
				daemo.setDaemon(true);// 
				daemo.start();
			}
			System.out.println("All daemo started");
			TimeUnit.MILLISECONDS.sleep(175);
		} catch(Exception e) {
			
		}
	}
	
	public void run() {
		try {
			throw new InterruptedException();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 

 
解決策:UncaughtExceptionHandlerインタフェース.このインタフェースは、スレッドが未キャプチャの異常で死に近づいたときに呼び出されます.
public class CaptureUncaughtException {
	public static void main(String[] args) {
		ExecutorService exe = Executors.newCachedThreadPool(new HandlerThreadFactory());
		exe.execute(new ExceptionThread2());
	}
}

class ExceptionThread2 implements Runnable {
	@Override
	public void run() {
		Thread t = Thread.currentThread();
		System.out.println("run() by " + t);
		System.out.println("eh = " + t.getUncaughtExceptionHandler());
		throw new RuntimeException();
	}
}

// , 
class HandlerThreadFactory implements ThreadFactory {
	@Override
	public Thread newThread(Runnable r) {
		Thread t = new Thread(r);
		t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
		System.out.println("eh = " + t.getUncaughtExceptionHandler());
		return t;
	}
}

// 
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.println("caught " + e);
	}
	
}