多线程基础--线程池

2018-09-13  本文已影响0人  collincp

正常项目中是不允许频繁创建线程。需要使用线程池来管理。jdk1.5后已经提供有管理线程池的API

代码实现:要求jdk版本1.5以上。当前版本为jdk 1.8

------------------------------------------代码实现-------------------------------------------

import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class ThreadPool {
private static int threadPoolSize = 2;
public static void main(String[] args) {
// 创建 Runnable 线程 将任务简单化,可以用内部类。线程任务更直观
Thread threadRun = new Thread (new Runnable() {
@Override
public void run() {
doRunTask();
}
});
// 创建有返回的线程任务
FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
String quest = "Callable call task and print task";
doCallable(quest);
return doCallable(quest);
}
});

   //线程启动 可以看出 启动的方式都是Thread进行 

// threadRun.start();//Thread 开始方法不可取
// new Thread(threadRun).start();//创建 线程启动 方法不可取
// new Thread(futureTask).start();//创建 线程启动 方法不可取

    //线程池启动任务 可以查看任务名称来看启动多少个
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(threadPoolSize); 
    fixedThreadPool.execute(threadRun);//无返回
    fixedThreadPool.submit(futureTask);//有返回

    String callResultPoll = null;
    try {
        callResultPoll = (String) futureTask.get();//特别注意 该方法会阻塞,如果没有获取到值会一直等待

// boolean doneBoolean = futureTask.isDone();//可以改方法来判断是非执行完
System.out.println(callResultPoll);//打印结果
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}

    /********************线程池添加任务************************/
    ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
    queue.offer("intput a");//添加数量大于线程数
    queue.offer("intput b");
    queue.offer("intput  c");
    queue.offer("intput d");
    queue.add(" intput e");
  
    Iterator<String> iterator = queue.iterator();
    while (iterator.hasNext()) {
        String qStr = iterator.next();
        FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                String quest = qStr;
                doCallable(quest);
                System.out.println(" threadName : " + Thread.currentThread().getName());
                //打印线程名称,可以看出while中将queue内容全部添加了,但是线程名称就两个
                return doCallable(quest);
            }
        });
        fixedThreadPool.submit(future);
        try {
            String callResult =future.get();
            System.out.println("callResult : " + callResult);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        
    }
    //当任务完成后,不需要线程,需要将线程池关闭
    fixedThreadPool.shutdown();
}
/**
 * doRunTask  执行 runnable具体的方法
 */

public static void doRunTask() {//main 为 static 导致方法也必须为static
String todo = "------do run task---------";
System.out.println( "线程名称:" + Thread.currentThread().getName()+ "| 任务 |" + todo);
}
/**
* 执行具体的callable方法,并返回处理结果
* @param docall 传入需要处理的参数
* @return 返回处理结果
*/
public static String doCallable(String docall) {
String todoCall ="线程名称:" + Thread.currentThread().getName()+ " |do call task | qeques:" + docall;
return todoCall;
}
}

------------------------------------------代码实现-------------------------------------------

代码实现中才是完整代码。简书对这个优化不是很好
心得:特别注意线程池添加任务中使用遍历方法将全部任务添加,该出其实是为每个需要处理的数据创建了一个线程。但是在是使用线程池管理,线程池启动线程。所以区分最小任务单位,能创建多少任务就创建多少任务。但是具体有多少线程就看线程池有多少线程。线程创建可以参考https://www.jianshu.com/p/640630c33b4c

上一篇 下一篇

猜你喜欢

热点阅读