1.1 shutdown() 和 shutdownNow()
方法shutdown()的作用是使当前未执行完的线程继续执行,而不再添加新的任务,
shutdown()方法是不阻塞的。
方法shutdownNow()的作用是中断所有的任务,并且抛出InterruptdException
异常(需要和任务中的if(Thread.currentThread().isInterrupted() == true) 结合使用)。
未执行的线程不再执行,也从执行队列中清除。
2.1 工厂ThreadFactory + UncaughtExceptionHandler 处理异常
可以通过重写ThreadFactory 中的newThread(Runnable r)方法来对线程的一些属性进行定制化。
2.2 代码
package com.lhc.concurrent.executor.factory;
import java.util.Date;
import java.util.concurrent.ThreadFactory;
public class MyTHreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("name:" + new Date());
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("自定义处理异常");
System.out.println(t.getName() + ":" + e.getMessage());
e.printStackTrace();
}
});
return thread;
}
}
2.3 测试类
package com.lhc.concurrent.executor.factory;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
//抛出异常
String str = null;
System.out.println(str.contains(""));
System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
}
public static void main(String[] srgs){
MyRunnable myRunnable = new MyRunnable();
ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 8, 20, TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>());
executor.setThreadFactory(new MyTHreadFactory());
executor.execute(myRunnable);
}
}
2.4运行结果
name:Mon May 13 17:16:57 GMT+08:00 2019 1557739017491
java.lang.NullPointerException
自定义处理异常
name:Mon May 13 17:16:57 GMT+08:00 2019:null
at com.lhc.concurrent.executor.factory.MyRunnable.run(MyRunnable.java:13)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at
java.lang.Thread.run(Thread.java:745)
3.1 方法afterExecute() 和 beforeExecute()
在线程池ThreadPoolExecutor 类中重写这两个方法可以对线程池中执行的线程对象实现监控。
3.2 代码
package com.lhc.concurrent.executor.before;
public class MyThread extends Thread{
public MyThread(String name) {
super();
this.setName(name);
}
@Override
public void run() {
System.out.println("打印了! begin" + this.getName() + " " + System.currentTimeMillis());
try {
Thread.sleep(4000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("打印了! end" + this.getName() + " " + System.currentTimeMillis());
}
}
3.3 测试类
package com.lhc.concurrent.executor.before;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyThreadPool extends ThreadPoolExecutor{
public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
System.out.println(((MyThread)r).getName() + "准备执行");
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
System.out.println(((MyThread)r).getName() + "执行完毕");
}
public static void main(String[] args){
MyThreadPool myThreadPool = new MyThreadPool(2, 2, Integer.MAX_VALUE,
TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
myThreadPool.execute(new MyThread("0001"));
myThreadPool.execute(new MyThread("0002"));
myThreadPool.execute(new MyThread("0003"));
myThreadPool.execute(new MyThread("0004"));
}
}
4.1 方法execute() 与submit的区别
1) 方法execute() 没有返回值,而submit()方法可以有返回值
2) 方法execute() 在默认的情况下异常直接抛出,不能捕获,但可以通过自定义ThreadFactory 的方式进行捕获,而submit()方法在默认的情况下,可以
捕获异常。