java并行流 阻塞主线程_多线程入门案例与java8的并行流
java8 實例請移步https://www.cnblogs.com/ngLee/p/14021859.html
進程與線程
進程是所有線程的集合,每一個線程是進程中的一條執行路徑。
多線程的創建方式,繼承Thread\實現Runable
/**
* 第一種創建線程的方式,繼承Thread
*/
public class MultiThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"....."+i);
}
}
}
/**
* 第二種,實現Runnable接口,更易于擴展。(多實現,單繼承)
*/
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.多線程創建 繼承Thread
MultiThread multiThread = new MultiThread();
Thread thread = new Thread(multiThread,"線程繼承Thread-1");
Thread thread2 = new Thread(multiThread,"線程繼承Thread-2");
//2.啟動多線程調用的是start(),而不是run()
thread.start();
thread2.start();
//3.打印效果 當前線程:線程1
/**********************************/
//2 實現Runnable
Runnable runnable = new MultiThread2();
Thread thread3 = new Thread(runnable,"線程實現Runnable-1");
Thread thread4 = new Thread(runnable,"線程實現Runnable-2");
thread3.start();
thread4.start();
//3 匿名內部類的方式
Thread thread5 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName()+"匿名內部類----"+i);
}
}
});
thread5.start();
System.out.println(Thread.currentThread().getName()+"---結束");
}
}
效果展示:并不是按照自上而下的執行
線程的幾個狀態
新建狀態:當用new操作符創建一個線程時, 例如new Thread(r),線程還沒有開始運行,此時線程處在新建狀態。 當一個線程處于新生狀態時,程序還沒有開始運行線程中的代碼。
就緒狀態:一個新創建的線程并不自動開始運行,要執行線程,必須調用線程的start()方法。當線程對象調用start()方法即啟動了線程,start()方法創建線程運行的系統資源,并調度線程運行run()方法。當start()方法返回后,線程就處于就緒狀態。處于就緒狀態的線程并不一定立即運行run()方法,線程還必須同其他線程競爭CPU時間,只有獲得CPU時間才可以運行線程。因為在單CPU的計算機系統中,不可能同時運行多個線程,一個時刻僅有一個線程處于運行狀態。因此此時可能有多個線程處于就緒狀態。對多個處于就緒狀態的線程是由Java運行時系統的線程調度程序(thread scheduler)來調度的。
運行狀態:當線程獲得CPU時間后,它才進入運行狀態,真正開始執行run()方法。
阻塞狀態:?線程運行過程中,可能由于各種原因進入阻塞狀態:
1>線程通過調用sleep方法進入睡眠狀態;
2>線程調用一個在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會返回到它的調用者;
3>線程試圖得到一個鎖,而該鎖正被其他線程持有;
4>線程在等待某個觸發條件;
死亡狀態:有兩個原因會導致線程死亡:1)run方法正常退出而自然死亡,2)一個未捕獲的異常終止了run方法而使線程猝死。為了確定線程在當前是否存活著(就是要么是可運行的,要么是被阻塞了),需要使用isAlive方法。如果是可運行或被阻塞,這個方法返回true; 如果線程仍舊是new狀態且不是可運行的, 或者線程死亡了,則返回false.
簡單需求:目前螞蟻課堂有10萬個用戶,現在螞蟻課堂需要做活動,給每一個用戶發送一條祝福短信
/**
* 提交實體
*/
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());
//短信發送接口
});
}
}
/**
* 測試類
*/
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);
}
//將數據進行分割,每組四千,這個每組數據量最好取配置,使用高峰期調低,保證不會超時
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
//使用并行流的時候,最好不要修改數據,如果需要map里的返回值,則用Collectors進行收集,不要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) {
//總數據量
int total = list.size();
//分組數量
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;
}
}
打印效果如圖,不是按順序打印,但這不正好就是多線程需要的效果的了嗎?
總結
以上是生活随笔為你收集整理的java并行流 阻塞主线程_多线程入门案例与java8的并行流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 储蓄国债快要发行了,你准备好资金了吗?
- 下一篇: java pojo 是什么_什么是POJ