Callable實現類介紹和函數式接口介紹


1:Callable實現類介紹

 

首先我們都知道,在Java中最常見的是繼承Thread類和實現Runnable接口來實現多線程(

 

這里我推薦采用實現接口的方式來實現多線程,原因有兩點:

 

1、Java的設計是單繼承的設計,如果采用繼承Thread的方式實現多線程則不能繼承其他的類

 

2、采用接口能夠更好的實現數據共享。線程的啟動需要Thread類的start方法,如果采用繼承的方式每次新建一個線程時,每個新建線程的數據都會單獨的存在線程內存中,這樣每個線程會單獨的操作自己線程的數據,不能更好的實現線程之間的數據共享)

 

但是無論以上哪種方式實現多線程,都存在一個問題,就是線程run方法沒有返回值,如果一個線程需要有返回值時,可以采用本章講的實現Callable接口來實現多線程

 

首先看一下Callable接口的源碼

 1 @FunctionalInterface
 2 public interface Callable<V> {
 3     /**
 4      * Computes a result, or throws an exception if unable to do so.
 5      *
 6      * @return computed result
 7      * @throws Exception if unable to compute a result
 8      */
 9     V call() throws Exception;
10 }

 

首先明確一點這是一個函數式接口,其中的@FunctionalInterface定義了這個接口為函數式接口(具體函數式接口和普通接口有何區別可以自行查閱相關資料) ,Callable接口接受一個泛型作為接口中call方法的返回值類型,因此我們在使用時需要傳入一個返回值類型。

 

然后我去實現這個接口來定義我自己的線程類,這里我傳入了一個String類型作為接口call方法的返回值類型,然后實現了call方法,將result作為返回結果返回

 1 public class MyCallable<String> implements Callable<String> {
 2  
 3     private int tickt=10;
 4     
 5     @Override
 6     public String call() throws Exception {
 7         // TODO Auto-generated method stub
 8         String result;
 9         while(tickt>0) {
10             System.out.println("票還剩余:"+tickt);
11             tickt--;
12         }
13         result=(String) "票已賣光";
14         return result;
15     }
16  
17 }

下面就看一下怎樣啟動采用實現Callable接口的線程

 1 package Multi_Thread;
 2 import org.apache.commons.io.FileUtils;
 3 
 4 import java.io.File;
 5 import java.io.IOException;
 6 import java.net.URL;
 7 import java.util.concurrent.*;
 8 
 9 /**
10  * 實現callable接口
11  */
12 public class CallMethod implements Callable<Boolean> {
13     String url;
14     String name;
15 
16     public CallMethod(String url, String name) {
17         this.url = url;
18         this.name = name;
19     }
20 
21     @Override
22     public Boolean call() {
23         WebDownloader down = new WebDownloader();
24         try {
25             down.downloader(url,name);
26         } catch (IOException e) {
27             e.printStackTrace();
28         }
29         return null;
30     }
31     class WebDownloader
32     {
33         public void downloader(String url,String name) throws IOException {
34             FileUtils.copyURLToFile(new URL(url),new File(name));
35         }
36     }
37 
38     public static void main(String[] args) throws ExecutionException, InterruptedException {
39         CallMethod callMethod = new CallMethod("https://csdnimg.cn/medal/github@240.png","a.png");
40         //創建執行服務
41         ExecutorService executorService = Executors.newFixedThreadPool(1);
42         //提交執行
43         Future<Boolean> submit = executorService.submit(callMethod);
44         //獲取jieguo
45         Boolean aBoolean = submit.get();
46         System.out.println(aBoolean);
47         executorService.shutdown();
48 
49     }
50 }

 

2:函數式接口

 

1. 函數式接口是個啥?

 

它是一個接口,在這個接口里面只能有一個抽象方法(但可以包含多個默認方法、靜態方法、繼承自Object的公有方法)。主要用於方法引用以及結合Lambda表達式使用。

 

2. 怎么定義?

 

@FunctionalInterface

public Interface MyFunction {
  public void do();
  //也可以包含如下方法
  //默認方法
  default void ddo() {
    //do what you want
  }
  //靜態方法
  public static void sdo() {
    //do what you want
  }
  //繼承自Object的公有方法
  @Override
  public boolean equals(Object obj);
}
3. 怎么用?
public void main(String[] args) {
  MyFunction mf = ()-> System.out.println("我是do方法");//l這個lambda表達式相當於實現了接口中的抽象方法,
  mf.do();
}
輸出:
我是do方法

注意:JDK7及其以下版本JDK只能包含公開且抽象的方法(默認由public abstract修飾),而JDK8開始可以包含default、static修飾的非抽象方法。

 


免責聲明!

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



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