1. 程式人生 > 其它 >Java核心類庫——執行緒

Java核心類庫——執行緒

一:多執行緒技術的概述:

1.直接看截圖:

電腦只能幹一件事情,學習多執行緒的意義在於讓多個路徑更合理的交替執行。CPU的高速切換給我們一種多個執行緒在同時執行的假象。

2.

二:執行緒講解:

1.多執行緒的第一種實現方式:

1.1)該類要實現Tread程序

1.2)程式碼演示:

程序1的類:

1 public class MyThread extends Thread{
2     @Override
3     public void run() {
4         for(int i = 0;i<10;i++){
5             System.out
.println("汗滴禾下土"+i); 6 } 7 } 8 }

Main()方法:

 1 public class Demo01 {
 2     public static void main(String[] args) {
 3         //建立執行緒物件
 4         MyThread thread = new MyThread();
 5         //啟動執行緒
 6         thread.start();
 7         for(int i = 0;i<10;i++){
 8             System.out.println("
鋤禾日當午"+i); 9 } 10 } 11 }

一下是對上述程式碼的解釋:

由一個執行緒呼叫的方法,該方法也會執行在這個執行緒中

2.執行緒的第二種實現方式:

2.1)實現Runnable()介面

2.2)程式碼演示:

執行緒1:

 1 /**
 2  * 用於給執行緒執行的任務
 3  */
 4 public class MyRunnable implement Runnable{
 5     @Override
 6     public void run() {
 7         for(int i = 0;i<10;i++){
 8             System.out
.println("汗滴禾下土"+i); 9 } 10 } 11 }

主執行緒(Main方法):

 1 public class Demo01 {
 2     public static void main(String[] args) {
 3         //1.建立一個任務物件
 4         MyRunnable runnable = new MyRunnable();
 5         //2.建立一個執行緒物件,並給他一個任務
 6         Thread t = new Thread(runnable);
 7         //3.啟動執行緒
 8         t.start();
 9         for(int i = 0;i<10;i++){
10             System.out.println("鋤禾日當午"+i);
11         }
12     }
13 }

列印的結果同上面相同

3.實現執行緒的兩種方式中,實現Runnable介面的優勢:

雖然Runnable介面很有優勢,但也會使用繼承Thread,因為它可以建立執行緒很方便:

 1 public class Demo02 {
 2     public static void main(String[] args) {
 3         //採用匿名內部類的方式建立執行緒
 4        new Thread(){
 5            @Override
 6            public void run() {
 7                for(int i = 0;i<10;i++){
 8                    System.out.println("鋤禾日當午"+i);
 9                }
10            }
11        }.start();
12         for(int i = 0;i<10;i++){
13             System.out.println("汗滴禾下土"+i);
14         }
15     }
16 }

4.執行緒中常見的方法

1.常見的構造方法

(name是給執行緒起的名字)

2.常用的方法:

2.1)getName();獲取執行緒的名字

2.2) getPriority();獲取執行緒的優先順序

2.3)getStatic();獲取執行緒的狀態

2.4)isAlive();判斷該執行緒是否活著

2.5)isDaemon();判斷該執行緒是否為守護執行緒

2.6)sleep(long millis);讓執行緒休眠多長的時間

2.7)sleep(lont millis,int nanos);

2.8)start();開始執行緒

2.9)

2.10)

3.執行緒技術的程式碼演示:

一:獲取和設定執行緒的名稱:

 1 public class Demo02 {
 2     public static void main(String[] args) {
 3         //首先打印出主程式的名稱
 4         System.out.println(Thread.currentThread().getName());
 5         //採用匿名內部類的方式建立一個執行緒
 6         new Thread(new MyRunnable(),"誰知盤中餐").start();
 7 
 8     }
 9     //建立一個靜態的內部類
10     static class MyRunnable implements Runnable{
11 
12         @Override
13         public void run() {
14             System.out.println(Thread.currentThread().getName());
15         }
16     }
17 }

currentThread()獲取當前的執行緒,返回的是一個執行緒

二:執行緒休眠sleep();

1 public class Demo02 {
2     public static void main(String[] args) throws InterruptedException {
3        for(int i = 0;i<10;i++){
4            System.out.println(i);
5            Thread.sleep(1000);
6        }
7     }
8 }

3.3)執行緒阻塞:可以理解為比較消耗時間的操作,比如一個執行緒要執行100行程式碼,其中有十行程式碼是讀取檔案,這個過程花費了比較多的時間,可以認為是執行緒阻塞。

常見的執行緒阻塞有讀取檔案,等待使用者輸入等

 1 public class Demo02 {
 2     /**
 3      * 需求:我想在Main()方法結束後終端子程式
 4      * 1.為子程式打一個標記
 5      * 2.在任務類中catch()塊中處理
 6      * @param args
 7      * @throws InterruptedException
 8      */
 9     public static void main(String[] args) throws InterruptedException {
10         Thread t = new Thread(new MyRunnable());
11         t.start();
12         for(int i = 0;i<5;i++){
13             System.out.println(Thread.currentThread().getName()+":"+i);
14         }
15         //1.為子程式打一個標記
16         t.interrupt();
17     }
18     static class MyRunnable implements Runnable{
19 
20         @Override
21         public void run() {
22             for(int i = 0;i<10;i++){
23                 System.out.println(Thread.currentThread().getName()+":"+i);
24                 try {
25                     Thread.sleep(1000);
26                 } catch (InterruptedException e) {
27                    // e.printStackTrace();
28                     //2.在任務類中catch()塊中處理
29                     System.out.println("你可以去死掉了");
30                     return;//結束該執行緒任務
31                 }
32             }
33         }
34     }
35 }

四:守護執行緒:

守護執行緒在啟動執行緒之前設定

 1 public class Demo02 {
 2     /**
 3      * 需求:我想在Main()方法結束後終端子程式
 4      * 1.為子程式打一個標記
 5      * 2.在任務類中catch()塊中處理
 6      * @param args
 7      * @throws InterruptedException
 8      */
 9     public static void main(String[] args) throws InterruptedException {
10         Thread t = new Thread(new MyRunnable());
11         //將他設定為守護執行緒
12         t.setDaemon(true);
13         t.start();
14         for(int i = 0;i<5;i++){
15             System.out.println(Thread.currentThread().getName()+":"+i);
16             Thread.sleep(1000);
17         }
18     }
19     static class MyRunnable implements Runnable{
20 
21         @Override
22         public void run() {
23             for(int i = 0;i<10;i++){
24                 System.out.println(Thread.currentThread().getName()+":"+i);
25                 try {
26                     Thread.sleep(1000);
27                 } catch (InterruptedException e) {
28                    // e.printStackTrace();
29                     //2.在任務類中catch()塊中處理
30                     System.out.println("你可以去死掉了");
31                     return;//結束該執行緒任務
32                 }
33             }
34         }
35     }
36 }

提取出來就是這個樣子:

1  Thread t = new Thread(new MyRunnable());
2          //將他設定為守護執行緒
3          t.setDaemon(true);
4          t.start();

五:執行緒安全問題:

1.執行緒不安全:當多個執行緒非同步處理同一個資料時,會導致資料不安全問題

2.1)程式碼演示(買票)

 1 public class Dem01 {
 2     public static void main(String[] args) {
 3         //建立任務物件
 4         Runnable run = new saleTicket();
 5         //一個任務被多個執行緒執行
 6         Thread t1 = new Thread(run);
 7         Thread t2 = new Thread(run);
 8         Thread t3 = new Thread(run);
 9         //啟動執行緒
10         t1.start();
11         t2.start();
12         t3.start();
13 
14     }
15     /**
16      * 寫一個任務類,進行賣票
17      */
18     static class saleTicket implements Runnable{
19         private //票的數量
20                 int count = 10;
21         @Override
22         public void run() {
23             while (count > 0) {
24                 System.out.println("正在售票");
25                 try {
26                     Thread.sleep(1000);
27                 } catch (InterruptedException e) {
28                     e.printStackTrace();
29                 }
30                 count--;
31                 System.out.println("還有餘票" + count);
32             }
33         }
34     }
35 }

這個結果顯然是不合理的,原因:當只剩最後一張票時,執行緒A先搶到時間戳,進入迴圈,此時她改變了count的數量變為0,但是,此時在他還沒有跳出迴圈的時候,執行緒B C 都進來了,就這導致後面出現餘票-1 -2的現象。

2.執行緒安全1——同步程式碼塊synchronized

2.1)語法:synchronized(同一個物件){ 排隊執行的程式碼塊 }

2.1)程式碼演示(對買票系統的改進)

 1 public class Dem01 {
 2     public static void main(String[] args) {
 3         //建立任務物件
 4         Runnable run = new saleTicket();
 5         //一個任務被多個執行緒執行
 6         Thread t1 = new Thread(run);
 7         Thread t2 = new Thread(run);
 8         Thread t3 = new Thread(run);
 9         //啟動執行緒
10         t2.start();
11         t1.start();
12         t3.start();
13 
14     }
15 
16     /**
17      * 寫一個任務類,進行賣票
18      */
19     static class saleTicket implements Runnable {
20         //票的數量
21         private int count = 10;
22         //建立一個物件,作為鎖
23         private Object o = new Object();
24         @Override
25         public void run() {
26             while (true) {
27                 synchronized (o) {
28                     if (count > 0) {
29                         System.out.println("正在售票");
30                         try {
31                             Thread.sleep(1000);
32                         } catch (InterruptedException e) {
33                             e.printStackTrace();
34                         }
35                         count--;
36                         System.out.println(Thread.currentThread().getName()+":還有餘票" + count);
37                     } else {
38                         break;
39                     }
40                 }
41             }
42         }
43     }
44 }

誰的執行緒先啟動,誰就先搶到時間戳,在後續中也會較快搶到時間戳,因為他離鎖最近

3.執行緒安全2——同步方法:

3.1)在任務類中,將方法程式碼塊抽去出來,將方法用synchronized修飾

3.2)程式碼演示(對買票的修改)

 1 public class Dem01 {
 2     public static void main(String[] args) {
 3         //建立任務物件
 4         Runnable run = new saleTicket();
 5         //一個任務被多個執行緒執行
 6         Thread t1 = new Thread(run);
 7         Thread t2 = new Thread(run);
 8         Thread t3 = new Thread(run);
 9         //啟動執行緒
10         t2.start();
11         t1.start();
12         t3.start();
13 
14     }
15 
16     /**
17      * 寫一個任務類,進行賣票
18      */
19     static class saleTicket implements Runnable {
20         //票的數量
21         private int count = 10;
22         @Override
23         public void run() {
24             while (true) {
25                 boolean flag = sale();
26                 if(!flag){
27                     break;
28                 }
29             }
30         }
31         public synchronized boolean sale(){
32             if (count > 0) {
33                 System.out.println("正在售票");
34                 try {
35                     Thread.sleep(1000);
36                 } catch (InterruptedException e) {
37                     e.printStackTrace();
38                 }
39                 count--;
40                 System.out.println(Thread.currentThread().getName()+":還有餘票" + count);
41                 return true;
42             }
43             return false;
44         }
45     }
46 }

同步方法的鎖物件就是建立該類的物件,就像是Runnable run = new saleTicket();只建立了一個任務,所有為同一把鎖

當同步程式碼塊和同步方法同時上鎖是,只有當一個鎖裡面完成後,才可以執行下一個鎖,就像兩個試衣間只有一個門一樣

4.執行緒安全3——顯示鎖Lock:

4.1)自己建立一個鎖物件。鎖Lock 類,他的子類reentrantLock

4.2)Lock l = new reentrantLock(); l.lock()上鎖 l.unlock()解鎖

4.3)程式碼演示(對售票的改進)

 1 import java.util.concurrent.locks.Lock;
 2 import java.util.concurrent.locks.ReentrantLock;
 3 
 4 public class Dem01 {
 5     public static void main(String[] args) {
 6         //建立任務物件
 7         Runnable run = new saleTicket();
 8         //一個任務被多個執行緒執行
 9         Thread t1 = new Thread(run);
10         Thread t2 = new Thread(run);
11         Thread t3 = new Thread(run);
12         //啟動執行緒
13         t2.start();
14         t1.start();
15         t3.start();
16 
17     }
18 
19     /**
20      * 寫一個任務類,進行賣票
21      */
22     static class saleTicket implements Runnable {
23         //票的數量
24         private int count = 10;
25         //建立鎖物件
26         private Lock l = new ReentrantLock();
27         
28         @Override
29         public void run() {
30             while (true) {
31                 //對需要排隊的程式碼塊進行上鎖
32                 l.lock();
33                 if (count > 0) {
34                     System.out.println("正在售票");
35                     try {
36                         Thread.sleep(1000);
37                     } catch (InterruptedException e) {
38                         e.printStackTrace();
39                     }
40                     count--;
41                     System.out.println(Thread.currentThread().getName() + ":還有餘票" + count);
42                 } else {
43                     break;
44                 }
45                 //程式碼塊執行完後解鎖
46                 l.unlock();
47             }
48         }
49     }
50 }

5.顯示鎖和隱式鎖的區別

5.1)定義:隱式鎖(Synchronized)是Java的關鍵字,當它用來修飾一個方法或一個程式碼塊時,能夠保證在同一時刻最多隻有一個執行緒執行該程式碼。因為當呼叫 Synchronized修飾的程式碼時,並不需要顯示的加鎖和解鎖的過程,所以稱之為隱式鎖。
顯示鎖(Lock)是一個介面,提供了無條件的、可輪詢的、定時的、可中斷的鎖獲取操作,所有的加鎖和解鎖操作方法都是顯示的,因而稱為顯示鎖。
5.2)區別:(9條訊息) 隱式鎖與顯示鎖的區別_ZL_do_it的部落格-CSDN部落格_顯示鎖和隱式鎖

6.公平鎖和非公平鎖:公平鎖是誰先來排隊,誰就先解鎖,非公平鎖就是誰先搶到誰就先解鎖。Java中預設的為非公平鎖,如何在Java中構建公平鎖:在顯示鎖中創 建 鎖物件時,Lock l = newReentrantLock(true);新增true

7.執行緒死鎖:

7.1)執行緒死鎖的原因:

7.2)程式碼演示:警察對罪犯說,你放了人質,我放了你;罪犯對警察說,你放了我,我放了人質。

 1 public class Demo02 {
 2     /**
 3      * 建立了兩個執行緒,兩個執行緒都在等待對方的回答,很有可能造成執行緒死鎖。
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         //建立警察和罪犯物件
 8         Culprit c = new Culprit();
 9         Police p = new Police();
10         //罪犯說話想要得到警察迴應
11         c.say(p);
12         //建立執行緒物件
13         new MyTread(c,p).start();
14     }
15 
16     static class MyTread extends Thread{
17         private Culprit c;
18         private Police p;
19 
20         public MyTread(Culprit c,Police p){
21             this.c = c;
22             this.p = p;
23         }
24         @Override
25         public void run() {
26             p.say(c);
27         }
28     }
29     static class Culprit{
30         //罪犯對警察說的話
31         //罪犯對警察說了話之後要得到警察的迴應
32         public synchronized void say(Police p){
33             System.out.println("你放了我,我放了罪犯");
34             p.fun();
35         }
36         //罪犯迴應警察的話
37         public synchronized void fun(){
38             System.out.println("我把人質留下,你放了我");
39         }
40     }
41 
42     static class Police{
43         //警察對罪犯說的話
44         //警察在說完話之後要得到罪犯的迴應
45         public synchronized void say(Culprit c){
46             System.out.println("你放了人質,我放了你");
47             c.fun();
48         }
49         //警察迴應罪犯
50         public synchronized void fun(){
51             System.out.println("把人質留下,你可以走了");
52         }
53     }
54 }

7.3)如何避免執行緒死鎖:在任何可能導致鎖產生的方法裡面,不要在呼叫其他有可能產生鎖的方法。不然的話極有可能產生死鎖的問題。

8.多執行緒通訊問題:

8.1)舉個栗子來描述一下場景:A執行緒去下載音樂,B執行緒要播放音樂,如何讓A執行緒現在完音樂後去告訴B執行緒你可以播放了,這就涉及到多執行緒間的通訊問題。

8.2)涉及這個問題時常用的方法:Object類中關於執行緒問題的方法:

8.3)程式碼演示(生產者和消費者的關係):這裡用廚師和服務員之間的關係來體現他。廚師做菜的時候,讓服務員這條執行緒休眠,廚師做好飯後,喚醒服務員,讓他去上菜,這個時候廚師休眠,等服務員端回盤子,喚醒廚師,讓他做菜,服務員再次休眠。就這樣迴圈。

  1 public class Demo03 {
  2     /**
  3      * 這是一個生產者和消費者兩個執行緒之間的關係,廚師生產一份飯,服務員端走一份,為了讓他們工作有序,就要讓一個在工作時,
  4      * 另一個在睡覺
  5      *
  6      * @param args
  7      */
  8     public static void main(String[] args) {
  9         //建立類物件
 10         Food f = new Food();
 11         Cook c = new Cook(f);
 12         c.start();
 13         Waiter w = new Waiter(f);
 14         w.start();
 15 
 16     }
 17 
 18     static class Food {
 19         private String name;
 20         private String taste;
 21 
 22         //true為做飯
 23         private boolean flag = true;
 24 
 25         //廚師做飯
 26         public void setNameAndTaste(String name, String taste) {
 27             if (flag) {
 28                 this.name = name;
 29                 try {
 30                     Thread.sleep(1000);
 31                 } catch (InterruptedException e) {
 32                     e.printStackTrace();
 33                 }
 34                 this.taste = taste;
 35                 flag = false;
 36 
 37                 //喚醒所有休眠的執行緒
 38                 this.notifyAll();
 39                 try {
 40                     //做好飯之後睡去,等待服務員喚醒
 41                     this.wait();
 42                 } catch (InterruptedException e) {
 43                     e.printStackTrace();
 44                 }
 45             }
 46         }
 47 
 48         //服務員獲取菜
 49         public void getFood() {
 50             if (!flag) {
 51                 try {
 52                     Thread.sleep(1000);
 53                 } catch (InterruptedException e) {
 54                     e.printStackTrace();
 55                 }
 56                 System.out.println("菜的名字是:" + name + ",味道是:" + taste);
 57                 flag = true;
 58                 this.notifyAll();
 59                 try {
 60                     this.wait();
 61                 } catch (InterruptedException e) {
 62                     e.printStackTrace();
 63                 }
 64             }
 65         }
 66     }
 67 
 68     static class Cook extends Thread {
 69         private Food f;
 70 
 71         public Cook(Food f) {
 72             this.f = f;
 73         }
 74 
 75         @Override
 76         public void run() {
 77             for (int i = 0; i < 10; i++) {
 78                 if (i % 2 == 0) {
 79                     f.setNameAndTaste("老乾媽小米粥", "香辣味");
 80                 } else {
 81                     f.setNameAndTaste("煎餅果子", "甜辣味");
 82                 }
 83             }
 84         }
 85 
 86     }
 87 
 88     static class Waiter extends Thread {
 89         private Food f;
 90 
 91         public Waiter(Food f) {
 92             this.f = f;
 93         }
 94 
 95         @Override
 96         public void run() {
 97             for (int i = 0; i < 10; i++) {
 98                 f.getFood();
 99             }
100         }
101     }
102 
103 }

9.執行緒的六種狀態:

10.帶返回值的執行緒Callable

10.1)這是一個介面

10.2)程式碼演示如何使1 import java.util.concurrent.Callable;2 import java.util.concurrent.ExecutionExcepti3 import java.util.concurrent.FutureTask;

 4 
 5 public class Demo04 {
 6     public static void main(String[] args) throws ExecutionException, InterruptedException {
 7         //2.建立一個Callable物件
 8         Callable<Integer> C = new MyCallable();
 9         //3.建立一個任務物件
10         FutureTask<Integer> f = new FutureTask<>(C);//f.isDone()判斷執行緒是否已經執行完了;f.cancel(true/false);決定是否取消執行緒,返回布林型別
11 //4.建立一個執行緒物件,將任務傳給他 12 new Thread(f).start(); 13 //當Callable執行緒呼叫了get方法後,主程式main就要等到子程式執行完後,得到一個返回值後,才可以執行 14 Integer j = f.get(); 15 System.out.println(j); 16 for(int i = 0;i<10;i++){ 17 Thread.sleep(100); 18 System.out.println(i); 19 } 20 } 21 22 //1.建立一個類,實現Callable<T>介面,注意他是泛型的 23 static class MyCallable implements Callable<Integer> { 24 25 @Override 26 public Integer call() throws Exception { 27 for(int i = 0;i<10;i++){ 28 Thread.sleep(100); 29 System.out.println(i); 30 } 31 return 100; 32 } 33 } 34 }

11.執行緒池:

1.概述:就是用來盛放執行緒的

2.執行緒池的底層原理之一

3.執行緒池的分類

1.快取執行緒池

1.2)程式碼演示

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         //1.建立執行緒池物件
 6         ExecutorService service = Executors.newCachedThreadPool();
 7         //2.向執行緒池中新增新的任務並且執行他
 8         service.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
12             }
13         });
14         service.execute(new Runnable() {
15             @Override
16             public void run() {
17                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
18             }
19         });
20         service.execute(new Runnable() {
21             @Override
22             public void run() {
23                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
24             }
25         });
26 
27         //讓主執行緒休眠1秒鐘,此時上述執行緒空閒,則不會在擴容,而用原來的執行緒
28         try {
29             Thread.sleep(1000);
30         } catch (InterruptedException e) {
31             e.printStackTrace();
32         }
33         service.execute(new Runnable() {
34             @Override
35             public void run() {
36                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
37             }
38         });
39     }
40 }

2.定長執行緒池

程式碼演示

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         //1.建立執行緒池物件
 6         ExecutorService service = Executors.newFixedThreadPool(2);
 7         //2.向執行緒池中新增新的任務並且執行他
 8         service.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
12                 try {
13                     Thread.sleep(3000);
14                 } catch (InterruptedException e) {
15                     e.printStackTrace();
16                 }
17             }
18         });
19         service.execute(new Runnable() {
20             @Override
21             public void run() {
22                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
23                 try {
24                     Thread.sleep(3000);
25                 } catch (InterruptedException e) {
26                     e.printStackTrace();
27                 }
28             }
29         });
30         service.execute(new Runnable() {
31             @Override
32             public void run() {
33                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
34             }
35         });
36 
37         //讓主執行緒休眠1秒鐘,此時上述執行緒空閒,則不會在擴容,而用原來的執行緒
38         try {
39             Thread.sleep(1000);
40         } catch (InterruptedException e) {
41             e.printStackTrace();
42         }
43         service.execute(new Runnable() {
44             @Override
45             public void run() {
46                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
47             }
48         });
49     }
50 }

3.單執行緒執行緒池

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         //1.建立執行緒池物件
 6         ExecutorService service =Executors.newSingleThreadExecutor();
 7         //2.向執行緒池中新增新的任務並且執行他
 8         service.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
12                 try {
13                     Thread.sleep(3000);
14                 } catch (InterruptedException e) {
15                     e.printStackTrace();
16                 }
17             }
18         });
19         service.execute(new Runnable() {
20             @Override
21             public void run() {
22                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
23                 try {
24                     Thread.sleep(3000);
25                 } catch (InterruptedException e) {
26                     e.printStackTrace();
27                 }
28             }
29         });
30 
31         //讓主執行緒休眠1秒鐘,此時上述執行緒空閒,則不會在擴容,而用原來的執行緒
32         try {
33             Thread.sleep(1000);
34         } catch (InterruptedException e) {
35             e.printStackTrace();
36         }
37         service.execute(new Runnable() {
38             @Override
39             public void run() {
40                 System.out.println(Thread.currentThread().getName()+":"+"鋤禾日當午");
41             }
42         });
43     }
44 }

4.週期定長執行緒池

4.1)定時執行一次

在5秒後會打印出 “鋤禾日當午”

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
 6         service.schedule(new Runnable() {
 7             @Override
 8             public void run() {
 9                 System.out.println("鋤禾日當午");
10             }
11         },5,TimeUnit.SECONDS);
12     }
13 }

4.2)週期定長執行任務

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
 6         service.scheduleAtFixedRate(new Runnable() {
 7             @Override
 8             public void run() {
 9                 System.out.println("汗滴禾下土");
10             }
11         },5,2,TimeUnit.SECONDS);
12     }
13 }

十二:lambda表示式:

1.函數語言程式設計思想

2.格式:Thread t = new Thread((我是引數) ->{我是方法體});

3.僅用來實現介面,實現的介面中只能有一個方法

4.使用的原因:減少冗餘

4.1)冗餘程式碼一:

public class Demo05 { public static void main(String[] args) {

        Thread t = new Thread(new MyRunnable());
t.start();
}
static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("誰知盤中餐");
}
}
}

4.2)冗餘程式碼二:
public class Demo05 {
public static void main(String[] args) {

new Thread(new Runnable() {
@Override
public void run() {
System.out.println("鋤禾日當午");
}
}).start();
}
}
採用Lamdba表示式:很簡潔
public class Demo05 {
public static void main(String[] args) {
new Thread(() -> System.out.println("鋤禾日當午")).start();
}
}


5.程式碼例項:

 1 public class Demo05 {
 2     public static void main(String[] args) {
 3         //面向物件思想
 4 //        print(new Main() {
 5 //            @Override
 6 //            public int sum(int x, int y) {
 7 //                return x+y;
 8 //            }
 9 //        },100,200);
10         //  }
11         
12         //Lambda表示式
13         print((int x,int y) ->{return x+y;},100,200);
14         
15     }
16     
17     public static void print(Main m,int x,int y){
18         int sum = m.sum(x, y);
19         System.out.println(sum);
20     }
21     static interface Main{
22         int sum(int x,int y);
23     }
24 }

結語

又學完了一個核心類庫了,加油。