欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

executor的execute和submit方法区别

程序员文章站 2022-03-04 17:37:22
...

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