日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java并行流 阻塞主线程_多线程入门案例与java8的并行流

發(fā)布時(shí)間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java并行流 阻塞主线程_多线程入门案例与java8的并行流 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

java8 實(shí)例請移步https://www.cnblogs.com/ngLee/p/14021859.html

進(jìn)程與線程

進(jìn)程是所有線程的集合,每一個線程是進(jìn)程中的一條執(zhí)行路徑。

多線程的創(chuàng)建方式,繼承Thread\實(shí)現(xiàn)Runable

/**

* 第一種創(chuàng)建線程的方式,繼承Thread

*/

public class MultiThread extends Thread{

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName()+"....."+i);

}

}

}

/**

* 第二種,實(shí)現(xiàn)Runnable接口,更易于擴(kuò)展。(多實(shí)現(xiàn),單繼承)

*/

public class MultiThread2 implements Runnable {

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName()+"---"+i);

}

}

}

/**

* 測試類

*/

public class TestThread {

public static void main(String[] args) {

System.out.println(Thread.currentThread().getName()+"---開始");

//1.多線程創(chuàng)建 繼承Thread

MultiThread multiThread = new MultiThread();

Thread thread = new Thread(multiThread,"線程繼承Thread-1");

Thread thread2 = new Thread(multiThread,"線程繼承Thread-2");

//2.啟動多線程調(diào)用的是start(),而不是run()

thread.start();

thread2.start();

//3.打印效果 當(dāng)前線程:線程1

/**********************************/

//2 實(shí)現(xiàn)Runnable

Runnable runnable = new MultiThread2();

Thread thread3 = new Thread(runnable,"線程實(shí)現(xiàn)Runnable-1");

Thread thread4 = new Thread(runnable,"線程實(shí)現(xiàn)Runnable-2");

thread3.start();

thread4.start();

//3 匿名內(nèi)部類的方式

Thread thread5 = new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 3; i++) {

System.out.println(Thread.currentThread().getName()+"匿名內(nèi)部類----"+i);

}

}

});

thread5.start();

System.out.println(Thread.currentThread().getName()+"---結(jié)束");

}

}

效果展示:并不是按照自上而下的執(zhí)行

線程的幾個狀態(tài)

新建狀態(tài):當(dāng)用new操作符創(chuàng)建一個線程時(shí), 例如new Thread(r),線程還沒有開始運(yùn)行,此時(shí)線程處在新建狀態(tài)。 當(dāng)一個線程處于新生狀態(tài)時(shí),程序還沒有開始運(yùn)行線程中的代碼。

就緒狀態(tài):一個新創(chuàng)建的線程并不自動開始運(yùn)行,要執(zhí)行線程,必須調(diào)用線程的start()方法。當(dāng)線程對象調(diào)用start()方法即啟動了線程,start()方法創(chuàng)建線程運(yùn)行的系統(tǒng)資源,并調(diào)度線程運(yùn)行run()方法。當(dāng)start()方法返回后,線程就處于就緒狀態(tài)。處于就緒狀態(tài)的線程并不一定立即運(yùn)行run()方法,線程還必須同其他線程競爭CPU時(shí)間,只有獲得CPU時(shí)間才可以運(yùn)行線程。因?yàn)樵趩蜟PU的計(jì)算機(jī)系統(tǒng)中,不可能同時(shí)運(yùn)行多個線程,一個時(shí)刻僅有一個線程處于運(yùn)行狀態(tài)。因此此時(shí)可能有多個線程處于就緒狀態(tài)。對多個處于就緒狀態(tài)的線程是由Java運(yùn)行時(shí)系統(tǒng)的線程調(diào)度程序(thread scheduler)來調(diào)度的。

運(yùn)行狀態(tài):當(dāng)線程獲得CPU時(shí)間后,它才進(jìn)入運(yùn)行狀態(tài),真正開始執(zhí)行run()方法。

阻塞狀態(tài):?線程運(yùn)行過程中,可能由于各種原因進(jìn)入阻塞狀態(tài):

1>線程通過調(diào)用sleep方法進(jìn)入睡眠狀態(tài);

2>線程調(diào)用一個在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會返回到它的調(diào)用者;

3>線程試圖得到一個鎖,而該鎖正被其他線程持有;

4>線程在等待某個觸發(fā)條件;

死亡狀態(tài):有兩個原因會導(dǎo)致線程死亡:1)run方法正常退出而自然死亡,2)一個未捕獲的異常終止了run方法而使線程猝死。為了確定線程在當(dāng)前是否存活著(就是要么是可運(yùn)行的,要么是被阻塞了),需要使用isAlive方法。如果是可運(yùn)行或被阻塞,這個方法返回true; 如果線程仍舊是new狀態(tài)且不是可運(yùn)行的, 或者線程死亡了,則返回false.

簡單需求:目前螞蟻課堂有10萬個用戶,現(xiàn)在螞蟻課堂需要做活動,給每一個用戶發(fā)送一條祝福短信

/**

* 提交實(shí)體

*/

public class UserThread extends Thread {

private List uList;

public UserThread(List uList){

this.uList = uList;

}

public List getuList() {

return uList;

}

public void setuList(List uList) {

this.uList = uList;

}

@Override

public void run() {

uList.stream().forEach(userEntity -> {

System.out.println("threadName:" + Thread.currentThread().getName() + "-用戶記錄序號:" + userEntity.getUno()

+ "---用戶名稱:" + userEntity.getUname());

//短信發(fā)送接口

});

}

}

/**

* 測試類

*/

public class TestThread {

public static void main(String[] args) {

//所有記錄

List list = new ArrayList<>();

for (int i = 0; i < 100; i++) {

UserEntity userEntity = new UserEntity();

userEntity.setUno("用戶id"+i);

userEntity.setUname("用戶名字"+i);

list.add(userEntity);

}

//將數(shù)據(jù)進(jìn)行分割,每組四千,這個每組數(shù)據(jù)量最好取配置,使用高峰期調(diào)低,保證不會超時(shí)

int everyNum = 20;

List> lists= spiltList(list,everyNum);

for (int i = 0; i < lists.size(); i++) {

Thread th = new UserThread(lists.get(i));

th.start();

}

//第二種java8 并行流,底層:ForkJoin --todo

//使用并行流的時(shí)候,最好不要修改數(shù)據(jù),如果需要map里的返回值,則用Collectors進(jìn)行收集,不要foreach里用list.add()

lists.parallelStream().forEach( lst -> {

lst.parallelStream().forEach( userEntity -> {

System.out.println("threadName:" + Thread.currentThread().getName() + "-用戶記錄序號:" + userEntity.getUno()

+ "---用戶名稱:" + userEntity.getUname());

});

});

}

private static List> spiltList(List list, int everyNum) {

//總數(shù)據(jù)量

int total = list.size();

//分組數(shù)量

int group = total%everyNum == 0 ? total/everyNum : total/everyNum +1 ;

//java8 stream

List userList = Stream.iterate(0, n->n+1).

limit(group).parallel().

map(seed -> {

List list1 = list.stream().skip(seed * everyNum).limit(everyNum).

collect(Collectors.toList());

return list1;

}

).collect(ArrayList::new,ArrayList::add,List::addAll);

return userList;

}

}

打印效果如圖,不是按順序打印,但這不正好就是多線程需要的效果的了嗎?

總結(jié)

以上是生活随笔為你收集整理的java并行流 阻塞主线程_多线程入门案例与java8的并行流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。