1. 程式人生 > 實用技巧 >實現多執行緒的四種方式

實現多執行緒的四種方式

package com.aaa.threaddemo;
/*
 * 一 實現多執行緒有哪四種方式?
 *     1.繼承Thread類
 *     2.實現runnable介面
 * 
 */
public class CreatThreadMethod {    
    public static void main(String[] args) {
        Demo2 thread2 = new Demo2();            //例項化 我們的demo2   thread
        Thread thread = new Thread(thread2);    //
把new的 demo2 thread 物件,放入Thread中 ,然後開啟start方法。 thread.start(); } } /* * 1 繼承一個thread類 * thread是runnable的實現類,代表一個執行緒的例項。 * 裡面有個一個native方法 start()方法,他可以啟動一個新的執行緒, * 並執行run方法 */ class Demo1 extends Thread{ @Override public void run() { System.out.println(
"繼承thread 重寫run方法 呼叫start, 開啟一個多執行緒"); } } /* * 二 實現runnable介面 * 注意!Java中只有單繼承機制,已經有繼承的子類如何實現多執行緒? * 可以考慮runnable介面。 * * 當我們的例項物件demo2實現runnable介面之後,還需要new一個Thread, * 把 demo2 當做target 傳入到Thread中,才能呼叫star方法,開啟多執行緒。 */ class Demo2 extends CreatThreadMethod implements
Runnable{ @Override public void run() { System.out.println("在繼承的基礎上,實現runnable介面,開啟多執行緒"); } }

三 有返回值的執行緒?

package com.aaa.threaddemo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/*
 * 一 實現多執行緒有哪四種方式?
 *  1.繼承Thread類
 *  2.實現runnable介面
 *  3.ExecutorService、Callable<Class>、Future 有返回值執行緒
 * 
 */
public class CreatThreadMethod {    
    public static void main(String[] args) {
        Demo2 thread2 = new Demo2();            //例項化 我們的demo2   thread
        Thread thread = new Thread(thread2);    //把new的 demo2  thread 物件,放入Thread中 ,然後開啟start方法。
        thread.start();            
    }
}

/*
 * 1 繼承一個thread類
 *         thread是runnable的實現類,代表一個執行緒的例項。
 *         裡面有個一個native方法   start()方法,他可以啟動一個新的執行緒,
 *         並執行run方法
 */
class Demo1 extends Thread{
    @Override
    public void run() {
        System.out.println("繼承thread 重寫run方法 呼叫start, 開啟一個多執行緒");
    }
    
}

/*
 * 二  實現runnable介面
 *         注意!Java中只有單繼承機制,已經有繼承的子類如何實現多執行緒?
 *         可以考慮runnable介面。
 * 
 *         當我們的例項物件demo2實現runnable介面之後,還需要new一個Thread,
 *         把 demo2 當做target 傳入到Thread中,才能呼叫star方法,開啟多執行緒。
 */
class Demo2 extends CreatThreadMethod implements Runnable{

    @Override
    public void run() {
        System.out.println("在繼承的基礎上,實現runnable介面,開啟多執行緒");
    }
    
}
/*
 * 三  有返回值執行緒? 
 *         在方法二中,我們實現的是runnable介面,這是一個沒有返回值的介面,那麼如果我是想要有返回值如何處理?
 *         實現callable介面
 * 
 *         執行callable後 可以獲取一個future物件,在該物件呼叫get,就能獲取到callable任務的object。
 *         再結合executor service 介面, 即可實現有返回結果的多執行緒
 * 
 *         newFixedThreadPool 建立一個固定的執行緒池
 */
class CallableFuture {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(2);        //newFixedThreadPool();  建立一個固定的執行緒池   2 個
        
        Demo3 threa1 = new Demo3("我是執行緒1,實現了callable介面");        //demo3 實現了callable介面
        Demo3 threa2 = new Demo3("我是執行緒2");

        Future future1 = pool.submit(threa1);                    //通過executor.submit提交一個Callable,返回一個Future,然後通過這個Future的get方法取得返回值。
        Future future2 = pool.submit(threa2);
                
        System.out.println(future1.get());            //Future 的get方法 獲得返回值。
        System.out.println(future2.get());
        
        pool.shutdown();        //關閉執行緒池
    }
}
/*
 ExecutorService 介面?
     <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);

一  callable 和 runnable介面的區別
    public interface Callable<V> {   
        V call() throws Exception;  
    }
        可以看到在callable裡面, 有一個泛型V call方法中返回一個這個型別的值
        
    interface Runnable {
      public abstract void run();
    }
        runnable 這裡是沒有返回值的
    
二  Future 是個啥?
    
    public interface Future<V> {
    boolean cancel(boolean var1);

    boolean isCancelled();

    boolean isDone();

    V get() throws InterruptedException, ExecutionException;

    V get(long var1, TimeUnit var3) throws InterruptedException, ExecutionException, TimeoutException;
}
    
    Future 也是一個介面,使用它的get()方法,可以獲得任務執行的返回值。
    
 */
class Demo3 implements Callable<Object>{
    
    private String threadName;

    public Demo3(String threadName) {
        this.threadName = threadName;
    }

    @Override
    public Object call() throws Exception {
        return "[threaName=" + threadName + "]" + "返回的資訊";
    }
}

四 執行緒池的方式

package com.aaa.threaddemo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/*
 * 一 實現多執行緒有哪四種方式?
 *     1.繼承Thread類
 *  2.實現runnable介面
 *  3.ExecutorService、Callable<Class>、Future 有返回值執行緒
 *  4.基於執行緒池的方式
 * 
 */
public class CreatThreadMethod {    
    public static void main(String[] args) {
        Demo2 thread2 = new Demo2();            //例項化 我們的demo2   thread
        Thread thread = new Thread(thread2);    //把new的 demo2  thread 物件,放入Thread中 ,然後開啟start方法。
        thread.start();            
    }
}

/*
 * 1 繼承一個thread類
 *         thread是runnable的實現類,代表一個執行緒的例項。
 *         裡面有個一個native方法   start()方法,他可以啟動一個新的執行緒,
 *         並執行run方法
 */
class Demo1 extends Thread{
    @Override
    public void run() {
        System.out.println("繼承thread 重寫run方法 呼叫start, 開啟一個多執行緒");
    }
    
}

/*
 * 二  實現runnable介面
 *         注意!Java中只有單繼承機制,已經有繼承的子類如何實現多執行緒?
 *         可以考慮runnable介面。
 * 
 *         當我們的例項物件demo2實現runnable介面之後,還需要new一個Thread,
 *         把 demo2 當做target 傳入到Thread中,才能呼叫star方法,開啟多執行緒。
 */
class Demo2 extends CreatThreadMethod implements Runnable{

    @Override
    public void run() {
        System.out.println("在繼承的基礎上,實現runnable介面,開啟多執行緒");
    }
    
}
/*
 * 三  有返回值執行緒? 
 *         在方法二中,我們實現的是runnable介面,這是一個沒有返回值的介面,那麼如果我是想要有返回值如何處理?
 *         實現callable介面
 * 
 *         執行callable後 可以獲取一個future物件,在該物件呼叫get,就能獲取到callable任務的object。
 *         再結合executor service 介面, 即可實現有返回結果的多執行緒
 * 
 *         newFixedThreadPool 建立一個固定的執行緒池
 */
class CallableFuture {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(2);        //newFixedThreadPool();  建立一個固定的執行緒池   2 個
        
        Demo3 threa1 = new Demo3("我是執行緒1,實現了callable介面");        //demo3 實現了callable介面
        Demo3 threa2 = new Demo3("我是執行緒2");

        Future future1 = pool.submit(threa1);                    //通過executor.submit提交一個Callable,返回一個Future,然後通過這個Future的get方法取得返回值。
        Future future2 = pool.submit(threa2);
                
        System.out.println(future1.get());            //Future 的get方法 獲得返回值。
        System.out.println(future2.get());
        
        pool.shutdown();        //關閉執行緒池
    }
}
/*
 ExecutorService 介面?
     <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);

一  callable 和 runnable介面的區別
    public interface Callable<V> {   
        V call() throws Exception;  
    }
        可以看到在callable裡面, 有一個泛型V call方法中返回一個這個型別的值
        
    interface Runnable {
      public abstract void run();
    }
        runnable 這裡是沒有返回值的
    
二  Future 是個啥?
    
    public interface Future<V> {
    boolean cancel(boolean var1);

    boolean isCancelled();

    boolean isDone();

    V get() throws InterruptedException, ExecutionException;

    V get(long var1, TimeUnit var3) throws InterruptedException, ExecutionException, TimeoutException;
}
    
    Future 也是一個介面,使用它的get()方法,可以獲得任務執行的返回值。
    
 */
class Demo3 implements Callable<Object>{
    
    private String threadName;

    public Demo3(String threadName) {
        this.threadName = threadName;
    }

    @Override
    public Object call() throws Exception {
        return "[threaName=" + threadName + "]" + "返回的資訊";
    }
}

/*
 * 為啥使用執行緒池?
 *    1 資源的寶貴性 一個執行緒系統中的建立是一個複雜的過程。
 *    2 便於管理 提高效率
 *  3 快取的策略   執行緒池
 * 
 * 
 */
class ThreadPool{
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(5);        //建立一個執行緒池  固定容量是5
        
        while(true){
            pool.execute(new Runnable() { //提交多個執行緒任務 並執行        
                @Override
                public void run() {
                    System.out.println( "當前執行緒【" +Thread.currentThread().getName() + "】 正在執行");
                    try {
                        Thread.sleep(3000);    //讓執行緒睡一會
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }    
}