正常项目中是不允许频繁创建线程。需要使用线程池来管理。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
网友评论