java new 多线程_Java多线程:Java多线程执行框架
為什么需要執行框架呢?
使用一般的new方法來創建線程有什么問題呢?一般的new線程的方式一般要給出一個實現了Runnable接口的執行類,在其中重寫run()方法,然后再在將這個執行類的對象傳給線程以完成初始化,這個過程中線程的定義和執行過程其實是雜糅在一起了,而且每次new一個新的線程出來在資源上很有可能會產生不必要的消耗,因此我們通過多線程執行框架來解決這兩個問題,其一可以分離線程的定義和執行過程,其二可以通過線程池來動態地管理線程以減小不必要的資源開銷。
線程執行框架啟動線程
將要多線程執行的任務封裝為一個Runnable對象,將其傳給一個執行框架Executor對象, Executor從線程池中選擇線程執行工作任務。
創建多線程框架對象調用線程執行任務
我們通常通過Executors類的一些靜態方法來實例化Executor或ThreadPoolExecutor對象:
比如Executor對象來執行:
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對象來執行:
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():一 個線程死掉后,自動重新創建后一個新的線程,所以沒有線程池的概念,不能被ThreadPoolExecutor接收;
Executors. newFixedThreadPool():固定數目的線程池;
Executors. newCachedThreadPool():動態地增加和減少線程數;
多線程框架對象調用線程執行任務取回結果
實現了Runnable接口的執行類雖然可以在run()方法里寫入執行體,但是無法返回結果值,因為run()方法是void型的,而Callable接口解決了這個問題,在繼承了Callable接口的執行類中重寫call()方法可以設置返回值,當Executor對象使用submit()函數提交執行類的時候會由線程池里的線程來運行,運行得到的返回值可以使用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;
}
}
多線程框架對象調用線程執行任務完成第一個還是全部完成就取回結果
使用submit()函數取回的結果不能控制任務是完成第一個還是全部完成就取回結果,然而使用invokeAny()和invokeAll()函數即可獲得這樣的效果,將執行體對象放入集合中傳入這兩個函數,前者可以在完成任務的多線程有一個(第一個)完成時就返回結果,因此結果類型是單結果,而后者則需要等待所有執行任務的線程都執行完畢才返回結果,因此結果仍是集合。
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;
}
}
多線程框架對象執行定時任務
使用Executor的schedule()函數族來調度線程池中的線程來執行callable執行類對象中的call()定時任務:
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;
}
}
總結
以上是生活随笔為你收集整理的java new 多线程_Java多线程:Java多线程执行框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 自旋锁_java锁的种类以及辨
- 下一篇: java arrays.equals_J