executor的execute和submit方法区别

executor经常会使用到,这里主要比较一下execute和submit方法的区别。

这个两个方法最主要的区别是如果runable中的方法抛出异常,execute会终止这个线程。而submit 不会。

这里分析一下原因。

测试代码:

ExecutorService es = Executors.newCachedThreadPool(namedThreadFactory);
		try {
			es.submit(new Runnable() {

				@Override
				public void run() {
					System.out.println("ok");
					throw new RuntimeException();
				}
			});
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		System.out.println("end");

 

其实两种方法提交给ThreadPoolExecutor执行的主要逻辑都是一致的,在ThreadPoolExecutor$Worker.run()中被执行,ThreadPoolExecutor$Worker是一个工作线程,每个Worker对象对应了一个线程, t会被调用start()。

    private Thread addThread(Runnable firstTask) {
        Worker w = new Worker(firstTask);
        Thread t = threadFactory.newThread(w);
        if (t != null) {
            w.thread = t;
            workers.add(w);
            int nt = ++poolSize;
            if (nt > largestPoolSize)
                largestPoolSize = nt;
        }
        return t;
    }

 

ThreadPoolExecutor$Worker.run():
	Runnable task = firstTask;
	firstTask = null;
	while (task != null || (task = getTask()) != null) {
	    runTask(task);
	    task = null;
	}

 注意如果没有没有任务,getTask会阻塞,然后都会执行runTask。 主要区别在于task对象的不同,sumit的task对象是FutureTask,而execute是一个普通的Runable。这里可以看到如果是Runable被执行调用run会抛出异常的,线程被中断。

runTask(Runnable task):
	boolean ran = false;
	beforeExecute(thread, task);
	try {
	    task.run();
	    ran = true;
	    afterExecute(task, null);
	    ++completedTasks;
	} catch (RuntimeException ex) {
	    if (!ran)
		afterExecute(task, ex);
	    throw ex;
	}

如果是FutureTask

void innerRun():
	try {
	    runner = Thread.currentThread();
	    if (getState() == RUNNING) 
		innerSet(callable.call());
	    else
		releaseShared(0); 
	} catch (Throwable ex) {
		innerSetException(ex);
	}

 

Thread [Action-thread-0] 	
	ThreadPoolExecutor$Worker.runTask(Runnable) line: 886	
	ThreadPoolExecutor$Worker.run() line: 908 [local variables unavailable]	
	Thread.run() line: 662	


Thread [Action-thread-0] 
	FutureTask$Sync.innerRun() line: 306 [local variables unavailable]	
	FutureTask<V>.run() line: 138 [local variables unavailable]	
	ThreadPoolExecutor$Worker.runTask(Runnable) line: 886	
	ThreadPoolExecutor$Worker.run() line: 908 [local variables unavailable]	
	Thread.run() line: 662	

 

猜你喜欢

转载自san-yun.iteye.com/blog/2072726