《Java 7 并发编程指南》学习概要 (1)join、daemon、UncaughtExceptionHandler 、中断

 

1、Thread 类的join() 方法


当前线程调用某个线程的这个方法时,它会暂停当前线程,直到被调用线程执行完成。


例子:

 

public class DataSourcesLoader implements Runnable{

    @Override
    public void run() {
       System.out.println(" ---Begin  DataSourcesLoader ---" );
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException ex) {
            Logger.getLogger(DataSourcesLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
       System.out.println(" ---End  DataSourcesLoader ---" );
    }
    
    public static void main(String[] args)
    {
       System.out.println(" ---Begin  Main ---" );
       Thread t = new Thread(new DataSourcesLoader());
       t.start();
        try {
            t.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(DataSourcesLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
       System.out.println(" ---End  Main ---" );
    }
}

 

输出为:

run:
 ---Begin  Main ---
 ---Begin  DataSourcesLoader ---
 ---End  DataSourcesLoader ---
 ---End  Main ---
BUILD SUCCESSFUL (total time: 4 seconds)

保证了  在t进程完成之后,main进程再完成。


2、守护线程setDaemon

 

当守护线程是程序里唯一在运行的线程时,JVM会结束守护线程并终止程序。

只能在start() 方法之前可以调用 setDaemon() 方法。一旦线程运行了,就不能修改守护状态。

可以使用 isDaemon() 方法来检查线程是否是守护线程(方法返回 true) 或者是使用者线程 (方法返回 false)

 

3、UncaughtExceptionHandler 接口

可以在线程里处理不受控制的异常

 

public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("Thread:" + t.getId());
        System.out.println("Thread status:" + t.getState());
        System.out.println("Exception:" + e.getMessage());
        System.out.println("Exception Stack Trace: ");
        e.printStackTrace(System.out);
    }

    public static void main(String[] args) {
        Thread t = new Thread(new MyTask());
        t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        t.start();
    }
}

class MyTask implements Runnable {

    @Override
    public void run() {
        System.out.println("----- start MyTask -----");
        if (true) {
            throw new RuntimeException("HAHAHAHHAHAHA");
        }
        System.out.println("----- end MyTask -----");
    }
}


输出

 

----- start MyTask -----
Thread:9
Thread status:RUNNABLE
Exception:HAHAHAHHAHAHA
Exception Stack Trace: 
java.lang.RuntimeException: HAHAHAHHAHAHA
at chapter1.MyTask.run(MyUncaughtExceptionHandler.java:37)
at java.lang.Thread.run(Thread.java:744)
BUILD SUCCESSFUL (total time: 0 seconds)

 

4、线程工厂ThreadFactory 生成线程

ThreadFactory 有一个方法:  public  Thread newThread(Runnable r)

public class MyThreadFactory implements ThreadFactory {

    private int counter;
    private String name;
    private List<String> stats;

    public MyThreadFactory(String name) {
        counter = 0;
        this.name = name;
        stats = new ArrayList<String>();
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r, name + "-Thread_" + counter);
        counter++;
        stats.add(String.format("created thread %d with name %s on %s\n", t.getId(), t.getName(), new Date()));
        return t;
    }

    public String getStats() {
        StringBuffer buffer = new StringBuffer();
        Iterator<String> it = stats.iterator();
        while (it.hasNext()) {
            buffer.append(it.next());
            buffer.append("\n");
        }
        return buffer.toString();
    }

    public static void main(String[] args) {
        MyThreadFactory factory = new MyThreadFactory("MyThreadFactory");
        Task task = new Task();
        Thread thread;
        System.out.printf("Starting the Threads\n");
        for (int i = 0; i < 10; i++) {
            thread = factory.newThread(task);
            thread.start();
        }
        System.out.printf("Factory stats:\n");
        System.out.printf("%s\n", factory.getStats());
    }
}

class Task implements Runnable {

    @Override
    public void run() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


5、线程中断 interrupt

 

public class InterruptTest {

	public static void main(String[] args) {

		Thread task = new PrimeGenerator();
		task.start();

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		task.interrupt();
	}
}

class PrimeGenerator extends Thread {

	@Override
	public void run() {
		long number = 1L;
		while (true) {
			if (isPrime(number)) {
				System.out.printf("Number %d is Prime", number);
			}
			if (isInterrupted()) {
				System.out.printf("The Prime Generator has been Interrupted");
				return;
			}
			number++;
		}
	}

	private boolean isPrime(long number) {
		if (number <= 2) {
			return true;
		}

		for (long i = 2; i < number; i++) {
			if ((number % i) == 0) {
				return false;
			}
		}
		return true;
	}

}


 

 

isInterrupted()和interrupted() 方法有着很重要的区别:

第一个不会改变interrupted属性值,但是第二个会设置成false。

interrupted() 方法是一个静态方法,建议使用isInterrupted()方法。

 

5、线程中断 InterruptException

如果线程实现的是由复杂的算法分成的一些方法,或者它的方法有递归调用,那么我们可以用更好的机制来控制线程中断。为了这个Java提供了InterruptedException异常。当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常。

 

public class InterruptExceptionTest {

	public static void main(String[] args) {

		FileSearch searcher = new FileSearch("C:\\", "autoexec.bat");
		Thread thread = new Thread(searcher);
		thread.start();

		try {
			TimeUnit.SECONDS.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		thread.interrupt();
	}
}

class FileSearch implements Runnable {

	private String initPath;
	private String fileName;

	public FileSearch(String initPath, String fileName) {
		this.initPath = initPath;
		this.fileName = fileName;
	}

	@Override
	public void run() {
		File file = new File(initPath);
		if (file.isDirectory()) {
			try {
				directoryProcess(file);
			} catch (InterruptedException e) {
				System.out.printf("%s: The search has been interrupted", Thread
						.currentThread().getName());
			}
		}
	}

	private void directoryProcess(File file) throws InterruptedException {
		File list[] = file.listFiles();
		if (list != null) {
			for (int i = 0; i < list.length; i++) {
				if (list[i].isDirectory()) {
					directoryProcess(list[i]);
				} else {
					fileProcess(list[i]);
				}
			}
		}
		if (Thread.interrupted()) {
			throw new InterruptedException();
		}
	}

	private void fileProcess(File file) throws InterruptedException {
		if (file.getName().equals(fileName)) {
			System.out.printf("%s : %s\n", Thread.currentThread().getName(),
					file.getAbsolutePath());
		}
		if (Thread.interrupted()) {
			throw new InterruptedException();
		}
	}

}


 



 

posted @ 2014-09-21 08:31  lihui1625  阅读(115)  评论(0编辑  收藏  举报