使用Executor
Executor管理Thread对象,从而简化了并发编程。Executor在客户端和任务执行之间提供了一个间接层;与客户端直接执行任务不同,这个中介对象将执行任务。 Executor允许管理一部任务的执行,而无须显式地管理线程的声明周期。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
- Created by Panda on 2018/6/4.
*/
public class CachedThreadPool {
public static void main (String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0 ; i < 5 ; i++) {
executorService.execute(new LiftOff());
}
executorService.shutdownNow();
}
}
CacheThreadPool:在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此是合理的Executor的首选。 FixedThreadPool使用的Thread对象的数量是 有界的。 SingThreadExecutor像是线程数量为1的FixedThreadPool。
从任务中产生返回值
Runnable是执行工作的独立任务,但是它不返回任何值。如果希望任务在完成时能返回一个值,可以实现Callable接口而不是Runnable接口。
import java.util.ArrayList;
import java.util.concurrent.*;
/**
* Created by Panda on 2018/6/4.
*/
class TaskWithResult implements Callable{
private int id;
public TaskWithResult (int id){
this .id=id;
}
@Override
public Object call () throws Exception {
return "result of TaskWithResult " +id;
}
}
public class CallableDemo {
public static void main (String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
ArrayList<Future<String>> futures=new ArrayList<>();
for (int i = 0 ; i < 10 ; i++) {
futures.add(executorService.submit(new TaskWithResult(i)));
}
for (Future<String> future:futures){
try {
System.out.println(future.get());
}catch (InterruptedException e){
System.out.println(e);
return ;
}catch (ExecutionException e){
System.out.println(e);
}finally {
executorService.shutdown();
}
}
}
/**
* result of TaskWithResult 0
result of TaskWithResult 1
result of TaskWithResult 2
result of TaskWithResult 3
result of TaskWithResult 4
result of TaskWithResult 5
result of TaskWithResult 6
result of TaskWithResult 7
result of TaskWithResult 8
result of TaskWithResult 9
*/
}
submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化。可以用isDone()方法来查询Future是否已经完成。当任务完成时,它具有一个结果,可以调用get()方法来获取该结果。也可以不用isDone()进行检查就直接调用get(),在这种情况下,get()将阻塞,直至结果准备就绪。还可以在试图调用get()来获取结果之前,先调用具有超时的get(),或者调用isDone()来查看任务是否完成。
后台线程
所谓后台线程,是指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程。反过来说,只要有任何非后台线程还在运行,程序就不会终止。
import java.util.concurrent.TimeUnit;
/**
* Created by Panda on 2018/6/4.
*/
public class SimpleDaemons implements Runnable {
@Override
public void run () {
try {
while (true ){
TimeUnit.MILLISECONDS.sleep(100 );
System.out.println(Thread.currentThread()+" " +this );
}
}catch (InterruptedException e){
System.out.println("sleep() interruptedException" );
}
}
public static void main (String[] args) throws Exception {
for (int i = 0 ; i <10 ; i++) {
Thread dameon = new Thread(new com21.SimpleDaemons());
dameon.setDaemon(true );
dameon.start();
}
System.out.println("All daemons started" );
/**
* All daemons started
Thread[Thread-6,5,main] com21.SimpleDaemons@79d62897
Thread[Thread-8,5,main] com21.SimpleDaemons@6bc0cd44
Thread[Thread-2,5,main] com21.SimpleDaemons@37c3a03e
Thread[Thread-7,5,main] com21.SimpleDaemons@480ca755
Thread[Thread-4,5,main] com21.SimpleDaemons@517f906c
Thread[Thread-3,5,main] com21.SimpleDaemons@14a1c9ea
Thread[Thread-0,5,main] com21.SimpleDaemons@d8488cb
Thread[Thread-5,5,main] com21.SimpleDaemons@47353e9f
Thread[Thread-9,5,main] com21.SimpleDaemons@564d9da5
Thread[Thread-1,5,main] com21.SimpleDaemons@3e31799e
*/
TimeUnit.MILLISECONDS.sleep(99 );
/**
* All daemons started
*/
}
}
import java.util.concurrent.*;
/**
* Created by Panda on 2018/6/4.
*/
class DaemonThreadFactory implements ThreadFactory {
@Override
public Thread newThread (Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true );
return thread;
}
}
public class DaemonFromFactory implements Runnable {
@Override
public void run () {
try {
while (true ){
TimeUnit.MILLISECONDS.sleep(100 );
System.out.println(Thread.currentThread()+"" +this );
}
}catch (InterruptedException e){
System.out.println("Interrupted" );
}
}
public static void main (String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool(new DaemonThreadFactory());
for (int i = 0 ; i < 10 ; i++) {
executorService.execute(new DaemonFromFactory());
}
System.out.println("All daemons started" );
TimeUnit.MILLISECONDS.sleep(500 );
}
}
import java.util.concurrent.TimeUnit;
/**
* Created by Panda on 2018/6/4.
*/
class InnerThread1{
private int countDown=5 ;
private Inner inner;
private class Inner extends Thread {
Inner(String name){
super (name);
start();
}
public void run (){
try {
while (true ){
System.out.println(this );
if (--countDown==0 ) return ;
sleep(10 );
}
}catch (InterruptedException e){
System.out.println("interrupted" );
}
}
public String toString (){
return getName()+": " +countDown;
}
}
public InnerThread1 (String name){
inner=new Inner(name);
}
}
class InnerThread2 {
private int countDown=5 ;
private Thread thread;
public InnerThread2 (String name){
thread=new Thread(name){
public void run (){
try {
while (true ){
System.out.println(this );
if (--countDown==0 )return ;
sleep(10 );
}
}catch (InterruptedException e){
System.out.println("sleep() interrupted" );
}
}
};
thread.start();
}
}
class InnerRunnable1{
private int countDown=5 ;
private Inner inner;
private class Inner implements Runnable {
Thread thread;
Inner(String name){
thread=new Thread(this ,name);
thread.start();
}
@Override
public void run () {
try {
while (true ){
System.out.println(this );
if (--countDown==0 ) return ;
TimeUnit.MILLISECONDS.sleep(10 );
}
}catch (InterruptedException e){
System.out.println("sleep() interrupted" );
}
}
public String toString (){
return thread.getName()+": " +countDown;
}
}
public InnerRunnable1 (String name){
inner=new Inner(name);
}
}
class InnerRunnable2{
private int countDown=5 ;
private Thread thread;
public InnerRunnable2 (String name){
thread=new Thread(new Runnable() {
@Override
public void run () {
try {
while (true ){
System.out.println(this );
if (--countDown==0 ) return ;
TimeUnit.MILLISECONDS.sleep(10 );
}
}catch (InterruptedException e){
System.out.println("sleep() interrupted" );
}
}
public String toString (){
return Thread.currentThread().getName()+": " +countDown;
}
},name);
thread.start();
}
}
class ThreadMethod{
private int countDown=5 ;
private Thread thread;
private String name;
public ThreadMethod (String name) {
this .name = name;
}
public void runTask (){
if (thread==null ){
thread=new Thread(name){
public void run (){
try {
while (true ){
System.out.println(this );
if (--countDown==0 ) return ;
sleep(10 );
}
}catch (InterruptedException e){
System.out.printf("sleep() interrupted" );
}
}
};
thread.start();
}
}
}
public class ThreadVariations {
public static void main (String[] args) {
new InnerThread1("InnerThread1" );
new InnerThread2("InnerThread2" );
new InnerRunnable1("InnerRunnable1" );
new InnerRunnable2("InnerRunnable2" );
new ThreadMethod("ThreadMethod" ).runTask();
}
}