`
free_flurry
  • 浏览: 3617 次
  • 性别: Icon_minigender_1
  • 来自: 福州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

如果把ExecutorService对象的引用弄丢了会怎么样?

阅读更多
以下是一段测试代码:
package test;
import java.util.*;
import java.math.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
public class Test3  {
	
	static class Task1 implements Runnable{
		public void  run(){
			System.out.println("Task1!");
			try{
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e){}
			for (int i=0;i<10;i++){
				System.out.println("Task1!"+" "+i);
				if (i%3==0) Thread.yield();
			}
			
		}
	}
	static class Task2 implements Runnable {
		
		public void run(){
			System.out.println("Task2!");
			try{
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e){}
			for (int i=0;i<10;i++){
				System.out.println("Task2!"+" "+i);
				if (i%3==0) Thread.yield();
			}
		}
	}
	static class Task3 implements Runnable {
		public void run(){
			System.out.println("Task3!");
			try{
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e){}
			for (int i=0;i<10;i++){
				System.out.println("Task3!"+" "+i);
				if (i%3==0) Thread.yield();
			}
		}
	}
	public static void main(String[] args){
		ExecutorService exec=Executors.newFixedThreadPool(2);
		exec.execute(new Task1());
		exec.execute(new Task2());
		//第三个任务需要在队列中等待
		exec.execute(new Task3());
		exec=null;
		//不执行shutdown的话这个程序就不会停止,这是与直接使用 Thread不同之处,
		//Thread一旦任务完成自动进入TERMINATED,而线程池中的线程不会,它只是处于WAITING中
//		exec.shutdown();
                  System.gc();
		System.out.print("The end of main()!\n");
                 
	}
}



输出结果就是:
Task1!
Task2!
The end of main()!
Task2! 0
Task2! 1
Task2! 2
Task2! 3
Task2! 4
Task2! 5
Task2! 6
Task2! 7
Task2! 8
Task2! 9
Task3!
Task1! 0
Task1! 1
Task1! 2
Task1! 3
Task1! 4
Task1! 5
Task1! 6
Task1! 7
Task1! 8
Task1! 9
Task3! 0
Task3! 1
Task3! 2
Task3! 3
Task3! 4
Task3! 5
Task3! 6
Task3! 7
Task3! 8
Task3! 9

首先,很显然的是,在Task1和Task2结束之前,exec已经为null,也就是ExecutorService对象丢失了。并且我们强制垃圾回收了。然而,所有的任务都正确执行完成了。换句话说,这也就意味着虽然我们丢失了对exec原来对象的引用(按照正常的理解,那应该会被回收掉的才对)但是ExecutorService对象仍然存活着,并且这个程序不会终止(因为我们没有调用shutdown方法)。事实证明,即使ExecutorService对象变成了“垃圾”也不会被回收,这与Thread对象一样,它们自己在JVM注册了“身份”,在运行完成前不会被当做垃圾回收。这也提醒了我们,要在正确时机关闭线程池,不然这个程序就不会自行结束了(当然对于CachedThreadPool而言,因为它的线程超时是1分钟,如果1分钟过后没有任务的话就会自行终止,当所有线程终止了,那池也关闭了)

0
0
分享到:
评论

相关推荐

    ExecutorService的execute和submit方法

    `submit()`方法会将任务提交到线程池,并返回一个`Future`对象,这个对象可以用来获取任务的执行结果、判断任务是否完成或者取消任务的执行。 1. `Future&lt;?&gt; submit(Runnable task)`:此方法将`Runnable`任务提交给...

    ExecutorService方法案例文件.zip

    ExecutorService方法案例文件.zip

    ExecutorService与CompletionService对比详解.docx

    然而,这种方式的问题在于,如果某个任务(如任务A)的执行时间较长,调用get()方法会阻塞,直到该任务完成,这将导致其他任务的结果无法及时处理,降低了整体效率。 为了解决这个问题,引入了CompletionService。...

    Executor,Executors,ExecutorService比较.docx

    线程池会尽可能重用已存在的线程,如果没有可用线程,会新建线程,当线程空闲时间超过60秒,线程会被终止。 - **newScheduledThreadPool(int corePoolSize)**:创建一个定长的调度线程池,支持定时及周期性任务执行...

    ExecutorService用法详解.doc

    接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。壹個 ExecutorService 实例因此特别像壹個线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现...

    ExecutorService线程池

    - `newCachedThreadPool()`:创建一个可缓存线程池,会尽可能重用已存在的线程,如果所有线程都在执行任务,新任务将创建新的线程。 - `newSingleThreadExecutor()`:创建一个单线程的线程池,所有的任务都会被串行...

    ExecutorService.shutdown()应该是在线程执行完毕后,才会去关闭

    然而,标题指出"ExecutorService.shutdown()应该是在线程执行完毕后,才会去关闭",这意味着`shutdown()`方法不会立即停止所有正在执行的任务,而是会等待这些任务完成后再关闭线程池。 `ExecutorService`提供了两...

    在spring boot中使用java线程池ExecutorService的讲解

    在 Spring Boot 中使用 Java 线程池 ExecutorService 的讲解 Spring Boot 作为一个流行的 Java 框架,提供了许多便捷的功能来帮助开发者快速构建应用程序。其中之一就是使用 Java 线程池 ExecutorService 来管理...

    java ExecutorService使用方法详解

    线程的生命周期由`ExecutorService`内部管理,如果线程完成了它的任务,`ExecutorService`会决定是否回收这个线程。 6. **线程的生命周期** 在`JobThread`的`run()`方法中,线程会持续运行,直到主线程将其从`...

    2_ExecutorService源码阅读1

    此方法用于启动有序关闭,意味着 ExecutorService 将不再接受新的任务,但会继续执行已经提交的任务直到它们完成。这是关闭服务的一个温和方式,通常在系统准备停止服务但需要等待所有已提交任务执行完毕时使用。 *...

    运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接JAVA语言

    运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接

    详解Java利用ExecutorService实现同步执行大量线程

    Java中的ExecutorService是Java并发编程的重要组成部分,它提供了一种高效、灵活的方式来管理和控制线程的执行。在处理大量线程或并发操作时,ExecutorService能够确保系统的稳定性和资源的有效利用,避免线程间的不...

    java线程池工具--ExecutorService,简单例子

    NULL 博文链接:https://x125858805.iteye.com/blog/2191873

    java并发编程:Executor、Executors、ExecutorService.docx

    Java并发编程中的Executor、Executors和ExecutorService是Java并发编程框架的重要组成部分,它们为开发者提供了高效管理和控制线程执行的工具。以下是对这些概念的详细解释: 1. Executor: Executor是一个接口,它...

    详解JDK中ExecutorService与Callable和Future对线程的支持

    Java并发编程中的ExecutorService、Callable和Future Java并发编程中,ExecutorService、Callable和Future是三大核心组件,它们之间紧密相连,共同实现了高效、安全的并发编程。下面我们将详细介绍这些组件的作用和...

    Java使用ExecutorService来停止线程服务

    Java 使用 ExecutorService 来停止线程服务 Java 中的 ExecutorService 是一个非常强大的线程池管理工具,它提供了多种方式来停止线程服务。今天,我们将详细介绍如何使用 ExecutorService 来停止线程服务。 首先...

    对象池

    3. **获取对象**:当需要对象时,首先检查池中是否有空闲对象,如果有则返回,否则创建新的对象并添加到池中。 4. **归还对象**:使用完对象后,不应直接删除,而是将其归还给对象池,以便后续再次使用。 5. **对象...

    Java 线程池ExecutorService详解及实例代码

    在处理大量并发任务时,如果每个任务都单独创建线程,那么频繁的线程创建和销毁会带来很大的性能开销。线程池可以预先创建一定数量的线程,待有任务提交时直接复用,避免了频繁创建和销毁线程的问题。此外,线程池还...

    关于java对象池的例子代码

    - 如果对象在使用过程中发生变化,可能导致对象状态不一致,影响程序正确性。 总结,对象池是Java中优化资源管理的一种常见技术,尤其适用于那些创建和销毁成本较高的对象。理解其工作原理并恰当应用,可以在不影响...

    运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接.doc

    `ServerSocket.accept()`方法用于阻塞等待新的客户端连接,一旦有客户端连接,它会返回一个新的`Socket`对象,代表与客户端的连接。在`service()`方法中,这个过程被无限循环执行,确保服务器始终准备接受新的连接。...

Global site tag (gtag.js) - Google Analytics