線程組和線程池的理解

上面我們瞭解了線程,接下來我們再來看看線程組

線程組:

  線程組表示一個線程的集合。此外,線程組也可以包含其他線程組

下面來看個例子:

package com.westos.Thread4;
 
public  class MyThread implements Runnable{
 
public void run() {
for(int x=0;x<10;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}

 

package com.westos.Thread4;
 
public class ThreadDome {
 
public static void main(String[] args) {

method1();
// method2();
}
 
//方式2:
private static void method2() {
//創建資源類對象
MyThread my=new MyThread();
//創建一個新的線程組對象
ThreadGroup tg=new ThreadGroup("牛鼻的線程組");
//創建Thread類對象,新的一種Thread類構造方法
//Thread(ThreadGroup group, Runnable target, String name)
Thread t1=new Thread(tg,my,"劉備");
Thread t2=new Thread(tg,my,"張飛");

//輸出線程組的名字
System.out.println(t1.getThreadGroup().getName());
System.out.println(t2.getThreadGroup().getName());
System.out.println(Thread.currentThread().getName());
}
 
//方式1:
private static void method1() {
//創建資源類對象
MyThread mt=new MyThread();
//創建線程對象
Thread t1=new Thread(mt,"線程1");
Thread t2=new Thread(mt,"線程2");
//調用Thread類中的getThreadGroup()方法,返回的是線程組
ThreadGroup tg1 = t1.getThreadGroup();
ThreadGroup tg2 = t2.getThreadGroup();

//然後輸出線程組的名字
System.out.println(tg1.getName());
System.out.println(tg2.getName());
System.out.println(Thread.currentThread().getName());
}
}
運行結果:
main
main
main
-------------
牛鼻的線程組
牛鼻的線程組
main

 

 

上面我們瞭解了線程組接下來我們再來看看線程池:

線程池: 可以說是線程的容器,當線程在start()方法執行後java虛擬機運行完run方法後,線程就會被當做垃圾一樣等待回收掉,但是線程池中的線程被執行後,他會重新回到線程池中等待被重新利用,這是線程池的好處

Executors: 一種工廠類

 

方法:

  和線程池的創建有關係

  public static ExecutorService newFixedThreadPool(int nThreads)

  創建一個可重用固定線程數的線程池

 

讓我們先來看看線程池的引入

例如:

package com.westos.Executor;
 
public class MyThread implements Runnable{
 
@Override
public void run() {

for(int x=0;x<7;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}

 

package com.westos.Executor;
/**
 * Executors類是一個有線程池有關的工廠類
 */
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class ExecutorDome {
 
public static void main(String[] args) {

//該方法可以確定線程池內線程的數量,返回的是一個線程池
//newFixedThreadPool(int nThreads, ThreadFactory threadFactory): 創建一個可重用固定線程數的線程池
ExecutorService ThreadGroupTool = Executors.newFixedThreadPool(2);

//提交Runnable接口的方法或者callable接口
ThreadGroupTool.submit(new MyThread());
ThreadGroupTool.submit(new MyThread());

//關閉線程池
//shutdown() 啓動一次順序關閉,執行以前提交的任務,但不接受新任務。
ThreadGroupTool.shutdown();
}
}
 
運行結果:
pool-1-thread-2:0
pool-1-thread-1:0
pool-1-thread-2:1
pool-1-thread-1:1
pool-1-thread-2:2
pool-1-thread-1:2
pool-1-thread-2:3
pool-1-thread-1:3
pool-1-thread-2:4
pool-1-thread-1:4
pool-1-thread-2:5
pool-1-thread-1:5
pool-1-thread-1:6
pool-1-thread-2:6

 

從上面的運行結果可以看出pool代表的就是線程池,後面跟的1就是線程池的數量,再後面的thread就是線程池中的線程了

 

我們在之前學習過了多線程的實現方式有兩種分別是:繼承Thread類和實現Runnable接口,接下來讓我們再看看實現多線程的第三種方式:線程池中實現Callable接口,在面試的時候,當考官詢問我們關於實現多線程的方式時,我們回答出前面學習的兩種就可以了,第三種如果能記得,那就更好了,可以爲你加分的

 

現在讓我們看看多線程的第三種實現方式:

package com.westos.Executor2;
 
import java.util.concurrent.Callable;
 
public class MyCallable implements Callable{
 
@Override
public Object call() throws Exception {
for(int x=0;x<7;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
return null;
}
 

}

 

 

package com.westos.Executor2;
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
/**
 * 實現多線程的第三種方式
 * 前提得自定義類去實現Callable接口
 */
public class ExecutorDome {
 
public static void main(String[] args) {

//調用Executor的返回線程池的方法
ExecutorService pool = Executors.newFixedThreadPool(2);

//提交 Callable接口的方法 
pool.submit(new MyCallable());
pool.submit(new MyCallable());

//關閉線程池
pool.shutdown();
}
}
運行結果:
pool-1-thread-1:0
pool-1-thread-1:1
pool-1-thread-1:2
pool-1-thread-1:3
pool-1-thread-1:4
pool-1-thread-1:5
pool-1-thread-1:6
pool-1-thread-2:0
pool-1-thread-2:1
pool-1-thread-2:2
pool-1-thread-2:3
pool-1-thread-2:4
pool-1-thread-2:5
pool-1-thread-2:6

 

可以看出依舊可以運行出多線程之間的特點

 

當我們想要實現線程之間的和運算應該怎麼做呢?

package com.westos.Executors;
 
import java.util.concurrent.Callable;
 
public class MyCallable implements Callable<Integer>{
 
//定義一個變量
private int number;
//創建該類的有參構造
public MyCallable(int number) {
this.number=number;
}
@Override
public Integer call() throws Exception {
int sum=0;
for(int x=0;x<=number;x++) {
sum+=x;
}
//因爲這裏需要返回線程之間的和的值,所以需要將null改爲sum
return sum;
}
 
}

 

 

package com.westos.Executors;
 
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
public class ExecutorsDome {
 
public static void main(String[] args) throws InterruptedException, ExecutionException {

//調用方法返回創建線程池
//ExecutorService:可以執行異步任務
ExecutorService pool = Executors.newFixedThreadPool(2);

//提交Callable方法,返回的是future接口
//Future 表示異步計算的結果
Future<Integer> f1 = pool.submit(new MyCallable(100));
Future<Integer> f2 = pool.submit(new MyCallable(200));

//get()  如有必要,等待計算完成,然後獲取其結果。
Integer i1 = f1.get();
Integer i2 = f2.get();

System.out.println(i1);
System.out.println(i2);
//關閉線程池
pool.shutdown();
}
}
運行結果:
5050
20100

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章