java new 多线程_Java多线程:Java多线程执行框架
為什么需要執(zhí)行框架呢?
使用一般的new方法來創(chuàng)建線程有什么問題呢?一般的new線程的方式一般要給出一個實現(xiàn)了Runnable接口的執(zhí)行類,在其中重寫run()方法,然后再在將這個執(zhí)行類的對象傳給線程以完成初始化,這個過程中線程的定義和執(zhí)行過程其實是雜糅在一起了,而且每次new一個新的線程出來在資源上很有可能會產(chǎn)生不必要的消耗,因此我們通過多線程執(zhí)行框架來解決這兩個問題,其一可以分離線程的定義和執(zhí)行過程,其二可以通過線程池來動態(tài)地管理線程以減小不必要的資源開銷。
線程執(zhí)行框架啟動線程
將要多線程執(zhí)行的任務(wù)封裝為一個Runnable對象,將其傳給一個執(zhí)行框架Executor對象, Executor從線程池中選擇線程執(zhí)行工作任務(wù)。
創(chuàng)建多線程框架對象調(diào)用線程執(zhí)行任務(wù)
我們通常通過Executors類的一些靜態(tài)方法來實例化Executor或ThreadPoolExecutor對象:
比如Executor對象來執(zhí)行:
public class ThreadTest {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new MyRunnable());
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("running");
}
}
比如線程池的Executor對象來執(zhí)行:
public class ThreadTest {
public static void main(String[] args) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
.newFixedThreadPool(3);
executor.execute(new MyRunnable());
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("running");
}
}
Executors. newSingleThreadExecutor():一 個線程死掉后,自動重新創(chuàng)建后一個新的線程,所以沒有線程池的概念,不能被ThreadPoolExecutor接收;
Executors. newFixedThreadPool():固定數(shù)目的線程池;
Executors. newCachedThreadPool():動態(tài)地增加和減少線程數(shù);
多線程框架對象調(diào)用線程執(zhí)行任務(wù)取回結(jié)果
實現(xiàn)了Runnable接口的執(zhí)行類雖然可以在run()方法里寫入執(zhí)行體,但是無法返回結(jié)果值,因為run()方法是void型的,而Callable接口解決了這個問題,在繼承了Callable接口的執(zhí)行類中重寫call()方法可以設(shè)置返回值,當(dāng)Executor對象使用submit()函數(shù)提交執(zhí)行類的時候會由線程池里的線程來運行,運行得到的返回值可以使用Future接口來接,取得的返回值類型由V決定,Future接口表示可能會得到的返回值,但是有可能報異常,因此要拋出這些異常,然后可以取得這些返回值。
public class ThreadTest {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
.newCachedThreadPool();
MyCallable myCallable = new MyCallable(2);
Future result = executor.submit(myCallable);
System.out.println(result.get());
}
}
class MyCallable implements Callable {
private int num;
public MyCallable(int num) {
this.num = num;
}
@Override
public Integer call() throws Exception {
return num * 2;
}
}
多線程框架對象調(diào)用線程執(zhí)行任務(wù)完成第一個還是全部完成就取回結(jié)果
使用submit()函數(shù)取回的結(jié)果不能控制任務(wù)是完成第一個還是全部完成就取回結(jié)果,然而使用invokeAny()和invokeAll()函數(shù)即可獲得這樣的效果,將執(zhí)行體對象放入集合中傳入這兩個函數(shù),前者可以在完成任務(wù)的多線程有一個(第一個)完成時就返回結(jié)果,因此結(jié)果類型是單結(jié)果,而后者則需要等待所有執(zhí)行任務(wù)的線程都執(zhí)行完畢才返回結(jié)果,因此結(jié)果仍是集合。
1.invokeAny():
public class ThreadTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
List callables = new ArrayList<>();
for(int i=0;i<10;i++){
MyCallable myCallable = new MyCallable(i);
callables.add(myCallable);
}
Integer res = executor.invokeAny(callables);
System.out.println(res);
}
}
class MyCallable implements Callable {
private int num;
public MyCallable(int num) {
this.num = num;
}
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " is running");
return num * 2;
}
}
2.invokeAll():
public class ThreadTest {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
.newFixedThreadPool(5);
List callables = new ArrayList();
for (int i = 0; i < 10; i++) {
MyCallable myCallable = new MyCallable(i);
callables.add(myCallable);
}
List> res = executor.invokeAll(callables);
for (Future future : res) {
System.out.println(future.get());
}
}
}
class MyCallable implements Callable {
private int num;
public MyCallable(int num) {
this.num = num;
}
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " is running");
return num * 2;
}
}
多線程框架對象執(zhí)行定時任務(wù)
使用Executor的schedule()函數(shù)族來調(diào)度線程池中的線程來執(zhí)行callable執(zhí)行類對象中的call()定時任務(wù):
public class ThreadTest {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
ScheduledExecutorService executorService = Executors
.newScheduledThreadPool(2);
MyCallable callable = new MyCallable(2);
executorService.schedule(callable, 10, TimeUnit.SECONDS);
executorService.shutdown();
}
}
class MyCallable implements Callable {
private int num;
public MyCallable(int num) {
this.num = num;
}
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " is running");
return num * 2;
}
}
總結(jié)
以上是生活随笔為你收集整理的java new 多线程_Java多线程:Java多线程执行框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 自旋锁_java锁的种类以及辨
- 下一篇: java遍历本地文件夹_JAVA遍历一个