• 《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
    ", 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("
    ");
            }
            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
    ");
            for (int i = 0; i < 10; i++) {
                thread = factory.newThread(task);
                thread.start();
            }
            System.out.printf("Factory stats:
    ");
            System.out.printf("%s
    ", 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
    ", Thread.currentThread().getName(),
    					file.getAbsolutePath());
    		}
    		if (Thread.interrupted()) {
    			throw new InterruptedException();
    		}
    	}
    
    }




  • 相关阅读:
    个人信息
    两个整数的最小公倍数和最大公约数
    java杨辉三角实现
    只会用这简单的递归求阶乘
    图形界面设计
    圆的面积,周长,圆柱体的体积(类的封装与抽象)
    杨辉三角
    1~10的阶乘java语言编程
    个人信息与计算器
    个人信息显示界面
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276435.html
Copyright © 2020-2023  润新知