java中線程切換的開銷


思路:

開三個線程A,B,C

線程A不斷的調用LockSupport.park()阻塞自己,一旦發現自己被喚醒,調用Thread.interrupted()清除interrupt標記位,同時增加自增計數

線程B不斷的調用線程A的interrupt()方法,將線程A從阻塞中喚醒,一旦喚醒成功,則自增計數

線程C定時輸出計數

 

代碼如下

 1 import java.util.concurrent.atomic.AtomicInteger;
 2 import java.util.concurrent.locks.LockSupport;
 3 
 4 /**
 5  * Created by cc on 2017/2/6.
 6  */
 7 public class Test {
 8     public static void main(String[] args) {
 9         final AtomicInteger count = new AtomicInteger(0);
10         final Thread thread = new Thread(new Runnable() {
11             public void run() {
12                 while (true) {
13                     LockSupport.park();
14                     Thread.interrupted();//clear interrupt flag
15                 }
16             }
17         });
18 
19         for(int i =0;i<1;i++) {
20             new Thread(new Runnable() {
21                 public void run() {
22                     while (true) {
23                         if (!thread.isInterrupted()) {
24                             thread.interrupt();
25                             count.incrementAndGet();
26                         }
27                     }
28                 }
29             }).start();
30         }
31         new Thread(new Runnable() {
32             public void run() {
33                 long last = 0;
34                 while (true) {
35                     try {
36                         Thread.sleep(1000);
37                         System.out.println(String.format("thread park %d times in 1s", count.get() - last));
38                         last = count.get();
39                     } catch (InterruptedException e) {
40                         e.printStackTrace();
41                     }
42                 }
43             }
44         }).start();
45 
46         thread.start();
47     }
48 }
View Code

 

測試環境是

CPU:I5 6500 ,默頻3.2G,測試的時候睿頻至3.3G出頭

內存:ddr4 2400 8g * 2,雙通道模式

 

測試結果如下

 1 thread park 380473 times in 1s
 2 thread park 376364 times in 1s
 3 thread park 371700 times in 1s
 4 thread park 374485 times in 1s
 5 thread park 375717 times in 1s
 6 thread park 380483 times in 1s
 7 thread park 370507 times in 1s
 8 thread park 382291 times in 1s
 9 thread park 377581 times in 1s
10 thread park 373198 times in 1s
11 thread park 371367 times in 1s
12 thread park 372876 times in 1s
13 thread park 394815 times in 1s
14 thread park 366434 times in 1s
15 thread park 391827 times in 1s
16 thread park 383691 times in 1s
17 thread park 380567 times in 1s
18 thread park 385234 times in 1s
19 thread park 367482 times in 1s
20 thread park 373650 times in 1s
21 thread park 375471 times in 1s
22 thread park 383743 times in 1s
23 thread park 377532 times in 1s
24 thread park 377353 times in 1s
25 thread park 386828 times in 1s
26 thread park 374503 times in 1s
27 thread park 373831 times in 1s
28 thread park 396207 times in 1s
29 thread park 374918 times in 1s
30 thread park 370150 times in 1s
31 thread park 378990 times in 1s
32 thread park 375449 times in 1s
33 thread park 406158 times in 1s
34 thread park 389793 times in 1s
35 thread park 371424 times in 1s
36 thread park 354746 times in 1s
37 thread park 384065 times in 1s
38 thread park 378894 times in 1s
39 thread park 358754 times in 1s
40 thread park 372588 times in 1s
View Code

大概每秒鍾能完成38w次線程切換,平均每次切換耗時2.63us

 

做個對比

在單線程運行時,每秒鍾可以完成1.6億次的AtomicLong.increaseAndGet()操作,可以完成33億次long型變量的自增操作

 

若干個數量級的差距,所以線程切換是一個開銷很大的操作,應當盡量注意


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM