代码如下:
package helloLucene;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class ThreadPool {
static Logger logger = Logger.getLogger("helloLucene.ThreadPool");
static {
PropertyConfigurator.configure("log4j.properties");
}
public static void oneThreadNoCatchException() {
/**
* new一个线程执行,线程内,把exception给线程,则进程死,何况线程
*/
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
logger.info("---------begin run---------");
while(true){
System.out.println(3/0);//此时进程死了,当然线程也死了
logger.info("---------after run---------");
}
}
});
thread.setName("thread1");
thread.start();
}
/**
* 如果catch 住了exception ,则线程会以为是正常的程序,而一直运行
*/
public static void oneThreadCatchException() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
logger.info("---------begin run---------");
while(true){
try{
System.out.println(3/0);//此时进程死了,当然线程也死了
logger.info("---------after run---------");
}catch(Exception ex){
logger.error("---------exception:---------" + ex);
}
}
}
});
thread.setName("thread1");
thread.start();
}
public static void threadPoolNoCatchException() throws InterruptedException {
/**
* 1.一旦有线程池里有exception,就止步于线程池了,不会往线程池外抛,也就是这里的scheduleTask()函数之外
* 2.线程池内出exception,如果被catch,则于其他程序无异
* 如果没catch exception,扔给了线程池的线程的run 方法,则线程不会死,会处于waiting 状态而不再执行了
* "pool-1-thread-1" prio=10 tid=0x00007f4e2c14c000 nid=0xfc0 waiting on condition [0x00007f4e242d6000]
java.lang.Thread.State: WAITING (parking)
3.所以线程池内的函数,最贴近线程池的run()方法的一层,一定要catch,否则就看不到exception 而一直卡主状态
*/
String schedule = "2";
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
logger.info("reschedule task with:" + schedule);
scheduleTask(service, new Runnable(){
public void run() {
try {
//while(true){//B方案加上while(true),和不加一样,thread waiting 状态,说明异常给了线程池,则他不调度了
System.out.println(3/0);//A 方案只有这句
//C方案把上面换成3/1,则线程池一直调度这个任务,3s 执行一次出发,线程是TIMED_WAITING 状态,只有当正好执行除法时,是Running 状态
//"pool-1-thread-1" prio=10 tid=0x00007ff51c12c000 nid=0x13d5 waiting on condition [0x00007ff512131000]
//java.lang.Thread.State: TIMED_WAITING (parking)
//}
}
finally {
logger.info("finally block");
}
}}, schedule);
Thread.sleep(20000);
scheduleTask(service, new Runnable(){
public void run() {
System.out.println("--------- enter second ---------");//上面的线程池中的线程处于WAITING之后,还能被线程池调度使用
}}, schedule);
}
public static void threadPoolCatchException() throws InterruptedException {
String schedule = "3";
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
logger.info("reschedule task with:" + schedule);
scheduleTask(service, new Runnable(){
public void run() {
try {
//while(true){//B方案加上while(true),和不加一样,thread waiting 状态,说明异常给了线程池,则他不调度了
System.out.println(3/0);//A 方案只有这句
//C方案把上面换成3/1,则线程池一直调度这个任务,3s 执行一次出发,线程是TIMED_WAITING 状态,只有当正好执行除法时,是Running 状态
//"pool-1-thread-1" prio=10 tid=0x00007ff51c12c000 nid=0x13d5 waiting on condition [0x00007ff512131000]
//java.lang.Thread.State: TIMED_WAITING (parking)
//}
}
catch (Exception e) {
logger.error("catch block : "+e);
}
finally {
logger.info("finally block");
}
}}, schedule);
}
private static void scheduleTask(ScheduledExecutorService service,
Runnable counteredTask, String schedule) {
service.scheduleWithFixedDelay(counteredTask, 1,
Long.parseLong(schedule), TimeUnit.SECONDS);
}
public static void main(String[] args) throws InterruptedException {
// oneThreadNoCatchException();
// oneThreadCatchException();
threadPoolNoCatchException();
// threadPoolCatchException();
}
}