介绍
进程和线程是实现并发的方法。进程是独立运行的程序实例,由操作系统直接进行调度管理。进程内部同样可以通过线程实现并发,常用于java的异步处理或者并行执行。
Runable
在Java 8中,Runable
是一个保持任务逻辑的单元。Runnable
是一个功能接口,可以使用lambda
函数实现。假设我们要触发电子邮件的虚拟任务。
Runable task () ->{
system.out.println("Triggering email from:" + Thread.currentThread().getName());
}
task.run();
在main函数中执行以上函数,您将会得到以下输出
Triggering email from: main
可以看到这个task仍然是在main线程里执行的,并不是我们想要的异步多线程效果。
Thread
Thread
类的实例接受一个Runable
作为参数,并且生成一个新的线程来执行Runable中的task。让我们更新上面的代码:
Runnable task = () -> {
System.out.println("Triggering email from: " + Thread.currentThread().getName());
};
Thread thread = new Thread(task);
thread.start();
System.out.println("This is the " + Thread.currentThread().getName() + " thread");
在main函数中执行以上代码,您将会得到以下输出:
This is the main Thread
Triggering email from: Thread-0
现在我们实现了使用多线程来完成异步执行。纯粹使用Thread的情况下,我们需要管理所有的Thread类的创建,这可能会比较麻烦,并且创建销毁也是有开销的。Java8中还提供了简单的线程池类给我们用。
Executors
引入ExecutorService作为高级实现,它不仅可以异步执行任务,还可以管理线程池。再更改上面的代码
Runnable task = () -> {
System.out.println("Triggering email from: " + Thread.currentThread().getName());
};
ExecutorService es = Executors.newFixedThreadPool(1);
es.submit(task);
System.out.println("This is the " + Thread.currentThread().getName() + " thread");
在main函数中执行以上代码,您将会得到以下输出:
This is the main thread
Triggering email from: pool-1-thread-1
需要注意的时,以上代码执行后,程序并不会退出。必须手动调用shutdown()
或者shutdownNow()
来终止程序。
Callable and Future
Runable 能够定义任务的执行单元,但是它没有返回值(返回void)。如果想要返回值怎么办?我们可以像用Runable一样用Callable
,并且得到一个Future
类实例的返回值。当task完成时,当前线程就能把结果装进这个Future。所以返回是异步的,需要通过Future.get()
方法阻塞并获得真正的返回值。
Callable<Integer> task = () -> {
System.out.println("Processing huge amount of data: "+Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(2);
return 1000000;
};
ExecutorService es = Executors.newFixedThreadPool(1);
Future<Integer> future = es.submit(task);
Integer result = future.get(); // 该方法会阻塞,直到future的内容被填充
System.out.println(result);
es.shutdown(); // 手动关闭线程池
System.out.println("This is the " + Thread.currentThread().getName() + " thread");
您将会得到以下输出:
Processing huge amount of data: pool-1-thread-1
1000000
This is the main thread