`

多线程:使用FutureTask获得线程返回值+同步线程

阅读更多
public class FutureTaskTest {

	public static void main(String[] args) {
		testMultiThreadExecutor();
	}

	public static void testFutureTask() {
		Callable<Integer> callable = new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				for (int i = 0; i < 10; i++) {
					System.out.println("Sleep " + i + " second");
					Thread.sleep(1000);
				}
				return 100;
			}
		};

		FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
		new Thread(futureTask).start();
		try {
			System.out.println("The main thread sleep 3 seconds");
			Thread.sleep(3000);
			System.out.println("The main thread sleep another 3 seconds");
			Thread.sleep(3000);
			System.out.println(futureTask.get());
			System.out.println("end");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}

	/**
	 * ExecutorService继承自Executor,它的目的是为我们管理Thread对象,从而简化并发编程,
	 * Executor使我们无需显示的去管理线程的生命周期,是JDK 5之后启动任务的首选方式
	 */
	public static void testSingleThreadExecutor() {
		//返回一个AbstractExecutorService的实现类的对象,AbstractExecutorService实现了submit(Callable), AbstractExecutorService的子类ThreadPoolExecutor中实现了execute(Runnable)
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		Future<Integer> future = threadPool.submit(new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				for (int i = 0; i < 10; i++) {
					System.out.println("Sleep " + i + " second");
					Thread.sleep(1000);
				}
				return 200;
			}
		});

		try {
			System.out.println("The main thread sleep 3 seconds");
			Thread.sleep(3000);
			System.out.println("The main thread sleep another 3 seconds");
			Thread.sleep(3000);
			System.out.println(future.get());
			System.out.println("end");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} finally {
			threadPool.shutdown(); // do NOT forget to shutdown thread pool
		}
	}

	public static void testMultiThreadExecutor() {
//		ExecutorService threadPool = Executors.newCachedThreadPool();
		int threadNumber = 5;
		ExecutorService threadPool = Executors.newFixedThreadPool(threadNumber);
		CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);
		for (int i = 0; i < threadNumber; i++) {
			final int taskID = i;
			cs.submit(new Callable<Integer>() {
				public Integer call() throws Exception {
					int totalSleep = new Random().nextInt(10);
					for (int i = 0; i < totalSleep; i++) {
						System.out.println(taskID + ": sleep " + i + " second of " + totalSleep);
						Thread.sleep(1000);
					}
					return taskID;
				}
			});
		}
		
		try {
			System.out.println("The main thread sleep 3 seconds");
			Thread.sleep(3000);
			System.out.println("The main thread sleep another 3 seconds");
			Thread.sleep(3000);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		} finally {
			threadPool.shutdown();
		}
		
		for (int i = 0; i < threadNumber; i++) {
			try {
				System.out.println(cs.take().get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		System.out.println("end");
	}
}
分享到:
评论

相关推荐

    史上最全 Java 多线程面试题及答案

    Java多线程是Java编程中不可或缺的一部分,它允许并发执行多个任务,从而提高应用程序的效率和响应速度。本文将深入探讨Java多线程的相关知识点,包括它的用途、创建线程的方式、start()与run()的区别、Runnable和...

    Java多线程

    Java中可以通过定义同步方法或使用同步块来实现线程同步。同步方法通过隐式锁定对象来防止多个线程同时访问,而同步块则可以更精确地控制同步范围。 #### 九、Java线程:并发协作-生产者消费者模型 生产者消费者...

    Android(Java)之多线程结果返回——Future 、FutureTask、Callable、Runnable

    在Android开发中,多线程是必不可少的一部分,特别是在执行耗时操作如网络请求、数据库操作等时,为了不阻塞主线程,我们会采用异步处理。`Future`、`FutureTask`、`Callable`和`Runnable`是Java并发编程中的核心...

    Java使用Callable和Future创建线程操作示例

    4. 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。 在示例代码中,我们首先使用Lambda表达式创建了一个Callable对象,然后将该实例包装成了一个FutureTask对象。主线程中当循环变量i等于20时,...

    有返回值的线程

    同时,`jdbctest`可能涉及到了如何在多线程环境下使用JDBC,比如在一个线程中执行查询,然后在另一个线程中处理结果,这与我们的主题“有返回值的线程”相吻合。 总之,要实现有返回值的线程,我们可以使用Java的`...

    多线程发邮件

    在多线程环境中,我们可以通过`FutureTask`将Callable转换为Runnable,这样就可以在ExecutorService中执行。`FutureTask`不仅可以代表一个Callable的结果,还可以用于取消任务或者检查任务是否完成。 提到...

    多线程单例模式并发访问

    操作系统通过调度算法来决定哪个线程获得CPU时间片,从而实现多线程程序的高效运行。 - **抢夺机制**:由于CPU资源有限,多线程环境下各个线程会“抢夺”CPU资源,即所谓的“抢占”。操作系统会根据一定的策略选择...

    Java 多线程学习总结6

    - **可见性**:使用volatile保证多线程间共享变量的可见性。 - **有序性**:使用volatile、synchronized或java.util.concurrent包中的工具类来保证指令的执行顺序。 通过深入理解以上知识点,开发者可以更好地...

    26_多线程_第1天(Thread、线程创建、线程池)_讲义

    在Java编程语言中,多线程是并发执行任务的关键机制,极大地提高了程序的效率和响应速度。本讲义主要探讨了三个核心主题:Thread类、线程创建以及线程池。 1. **Thread类** Java中的`Thread`类是所有线程的基础,...

    java多线程

    Java多线程机制还包括线程安全、线程同步(synchronized、Lock等)、线程池、死锁避免、中断和守护线程等概念。熟练掌握这些知识点,能帮助开发者编写出高效、稳定且易于维护的多线程Java程序。

    java多线程返回值使用示例(callable与futuretask)

    为了解决这个问题,Java提供了`Callable`接口和`FutureTask`类,它们是实现多线程返回值的关键工具。 `Callable`接口类似于`Runnable`,但比它功能更强大。`Callable`接口中的`call()`方法可以返回一个结果,并且...

    多线程高频60道面试题

    - **使用ExecutorService、Callable、Future**:创建线程池,提交Callable任务,获取Future结果,支持带返回值的多线程。 4. **启动线程的方法start()与run()**: - **start()**:启动线程,使线程进入就绪状态,...

    03 多线程开发如此简单—Java中如何编写多线程程序.pdf

    FutureTask提供了有返回值的多线程操作,它实现了Future接口,可以用来获取线程执行的结果。Executor框架是Java并发编程的强大工具,它提供了线程池服务,能够有效地管理和控制线程,避免频繁创建和销毁线程带来的...

    多线程操作实例源码

    本实例源码主要聚焦于多线程操作,旨在通过具体的代码示例来帮助开发者理解和掌握多线程的使用。 在Java等支持多线程的编程语言中,创建和管理线程主要有以下几种方式: 1. 继承Thread类:这是最基础的创建线程的...

    40个Java多线程问题总结

    - 当今计算机硬件普遍配备有多核CPU,利用多线程技术能够有效地分配任务到不同的核心上,使得计算资源得到最大化利用。在双核CPU上,若仅使用单线程,则约有一半的处理能力被闲置;而在四核或更多核的处理器上,未...

    javase之多线程技术

    使用多线程的原因: - **提高效率**:通过并发执行,可以更好地利用系统资源,尤其是多核CPU。 - **并发与串行**:并发提高了系统响应速度,但并不意味着绝对的执行速度提升,因为存在CPU上下文切换开销。 **线程池...

    多线程面试59题.pdf

    ### 多线程的核心知识点详解 #### 一、多线程的作用 1. **发挥多核CPU优势**: - **背景**:现代计算机硬件普遍采用多核CPU设计,例如常见的双核、四核甚至是十六核CPU。这些多核处理器的设计初衷是为了提高计算...

    Java多线程-JDK5.0新增线程创建方式

    ### Java多线程-JDK5.0新增线程创建方式 #### 一、新增方式1:实现Callable接口 ##### (1)介绍 自Java 5.0起,为提高线程管理的灵活性与效率,引入了`Callable`接口,这是一种全新的创建线程的方式。与传统的`...

Global site tag (gtag.js) - Google Analytics