1. 程式人生 > >JAVA多執行緒實現的幾種方式及簡單示例

JAVA多執行緒實現的幾種方式及簡單示例

 JAVA多執行緒的實現方式是JAVA基礎的一個重點,看過好多次,但不經常用就容易忘記,今天做一個總結,算是把JAVA基礎再夯實一下。

Java多執行緒實現方式主要有四種:繼承Thread類、實現Runnable介面、實現Callable介面通過FutureTask包裝器來建立Thread執行緒、使用ExecutorService、Callable、Future實現有返回結果的多執行緒。

1、繼承Thread類建立執行緒
Thread類本質上是實現了Runnable介面的一個例項,代表一個執行緒的例項。啟動執行緒的唯一方法就是通過Thread類的start()例項方法。start()方法是一個native方法,它將啟動一個新執行緒,並執行run()方法。這種方式實現多執行緒很簡單,通過自己的類直接extend Thread,並複寫run()方法,就可以啟動新執行緒並執行自己定義的run()方法。例如:

public class MyThread extends Thread {
	public void run() {
		while(true) {
			System.out.println(this.getName()+" running...");
			try {
                Thread.sleep(1000); // 休息1000ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
		}
	}
	public static void main(String[]args) {
		MyThread thread1 = new MyThread();
		MyThread thread2 = new MyThread();
		thread1.start();
		thread2.start();
	}
}

//執行結果
Thread-1 running...
Thread-0 running...
Thread-1 running...
Thread-0 running...
Thread-1 running...
Thread-0 running...
Thread-1 running...
Thread-0 running...
Thread-1 running...
Thread-0 running...
Thread-1 running...
Thread-0 running...

注意:此時除了建立的兩個執行緒外,還有main執行緒也就是主執行緒在執行,另外還有負責垃圾回收的執行緒同樣在執行,這裡不予研究。執行緒的名字在建立執行緒是預設配置,也可以在建立執行緒時傳入執行緒名字,例如

 MultiThreadDemo td1 = new MultiThreadDemo("t1"); // 指定執行緒的名字

2、實現Runnable介面

實現Runnable介面也是一種常見的建立執行緒的方式。使用介面的方式可以讓我們的程式降低耦合度。Runnable介面中僅僅定義了一個方法,就是run。

其實Runnable就是一個執行緒任務,執行緒任務和執行緒的控制分離,這也就是上面所說的解耦。我們要實現一個執行緒,可以藉助Thread類,Thread類要執行的任務就可以由實現了Runnable介面的類來處理。 這就是Runnable的精髓之所在!

例如:

//整合Runnable介面定義任務類
public class ThreadTask implements Runnable {

	@Override
	public void run() {
			while(true) {
			System.out.println(Thread.currentThread().getName()+" is running...");
			try {
	            Thread.sleep(1000);
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
		}
	}
}


//在main方法中建立執行緒去完成該任務
public class Main extends ThreadTask {
	public static void main(String[]args) {
		ThreadTask task = new ThreadTask();//新建任務類
		Thread t1 = new Thread(task);
		t1.start();
		Thread t2 = new Thread(task);
		t2.start();
	}
}

下面通過多個售票員同時執行售票任務的例子來認識多執行緒

//建立售票任務
public class TicketSailTask implements Runnable{
	public static int number = 100;//總共有100張票
	public Object lock = new Object();//建立鎖,防止多個執行緒同時賣同一張票
	@Override
	public void run() {
		while(true) {
			//進行同步
			synchronized(lock) {
				try{
					Thread.sleep(100);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
			if(number>0) {
				System.out.println(Thread.currentThread().getName()+"正在賣第"+number+"張票");
				number--;
			}else {
				break;
			}
		}
	}
}

//建立多個執行緒,執行任務
public class Main extends ThreadTask {
	public static void main(String[]args) {
		TicketSailTask task = new TicketSailTask();//新建任務類
		Thread t1 = new Thread(task,"小王");
		t1.start();
		Thread t2 = new Thread(task,"小劉");
		t2.start();
		Thread t3 = new Thread(task,"小李");
	}
}

//執行結果
小王正在賣第100張票
小劉正在賣第99張票
小劉正在賣第98張票
小王正在賣第97張票
小劉正在賣第96張票
小王正在賣第95張票
小劉正在賣第94張票
小劉正在賣第93張票
小王正在賣第92張票
小劉正在賣第91張票
小王正在賣第90張票
小劉正在賣第89張票
小王正在賣第88張票
小劉正在賣第87張票
。。。。

3、實現Callable介面實現多執行緒

與實現Runnable介面實現多執行緒類似,也有不同

相同點:
兩者都可用來編寫多執行緒程式;
兩者都需要呼叫Thread.start()啟動執行緒;
 

不同點:

兩者最大的不同點是:實現Callable介面的任務執行緒能返回執行結果;而實現Runnable介面的任務執行緒不能返回結果;
Callable介面的call()方法允許丟擲異常;而Runnable介面的run()方法的異常只能在內部消化,不能繼續上拋;

package com.callable.runnable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableImpl implements Callable<String> {

    public CallableImpl(String acceptStr) {
        this.acceptStr = acceptStr;
    }

    private String acceptStr;

    @Override
    public String call() throws Exception {
        // 任務阻塞 1 秒
        Thread.sleep(1000);
        return this.acceptStr + " append some chars and return it!";
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<String> callable = new CallableImpl("my callable test!");
        FutureTask<String> task = new FutureTask<>(callable);
        long beginTime = System.currentTimeMillis();
        // 建立執行緒
        new Thread(task).start();
        // 呼叫get()阻塞主執行緒,反之,執行緒不會阻塞
        String result = task.get();
        long endTime = System.currentTimeMillis();
        System.out.println("hello : " + result);
        System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!");
    }
}

//執行結果

hello : my callable test! append some chars and return it!
cast : 1 second!

Process finished with exit code 0

4、通過執行緒池來實現多執行緒

public class ThreadDemo05{

    private static int POOL_NUM = 10;     //執行緒池數量

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        ExecutorService executorService = Executors.newFixedThreadPool(5);  
        for(int i = 0; i<POOL_NUM; i++)  
        {  
            RunnableThread thread = new RunnableThread();

            //Thread.sleep(1000);
            executorService.execute(thread);  
        }
        //關閉執行緒池
        executorService.shutdown(); 
    }   

}

class RunnableThread implements Runnable  
{     
    @Override
    public void run()  
    {  
        System.out.println("通過執行緒池方式建立的執行緒:" + Thread.currentThread().getName() + " ");  

    }  
}

執行結果
通過執行緒池方式建立的執行緒:pool-1-thread-3  
通過執行緒池方式建立的執行緒:pool-1-thread-4  
通過執行緒池方式建立的執行緒:pool-1-thread-1  
通過執行緒池方式建立的執行緒:pool-1-thread-5  
通過執行緒池方式建立的執行緒:pool-1-thread-2  
通過執行緒池方式建立的執行緒:pool-1-thread-5  
通過執行緒池方式建立的執行緒:pool-1-thread-1  
通過執行緒池方式建立的執行緒:pool-1-thread-4  
通過執行緒池方式建立的執行緒:pool-1-thread-3  
通過執行緒池方式建立的執行緒:pool-1-thread-2

這裡增加一點執行緒狀態的知識

這裡寫圖片描述

執行緒總共有5大狀態,通過上面第二個知識點的介紹,理解起來就簡單了。

新建狀態:新建執行緒物件,並沒有呼叫start()方法之前

就緒狀態:呼叫start()方法之後執行緒就進入就緒狀態,但是並不是說只要呼叫start()方法執行緒就馬上變為當前執行緒,在變為當前執行緒之前都是為就緒狀態。值得一提的是,執行緒在睡眠和掛起中恢復的時候也會進入就緒狀態哦。

執行狀態:執行緒被設定為當前執行緒,開始執行run()方法。就是執行緒進入執行狀態

阻塞狀態:執行緒被暫停,比如說呼叫sleep()方法後執行緒就進入阻塞狀態

死亡狀態:執行緒執行結束

相關推薦

JAVA執行實現方式簡單示例

 JAVA多執行緒的實現方式是JAVA基礎的一個重點,看過好多次,但不經常用就容易忘記,今天做一個總結,算是把JAVA基礎再夯實一下。 Java多執行緒實現方式主要有四種:繼承Thread類、實現Runnable介面、實現Callable介面通過FutureTask包裝器來

實現java執行的3方式,99%人沒用過第3

實現多執行緒的3種方式 1、繼承Thread類 看jdk原始碼可以發現,Thread類其實是實現了Runnable介面的一個例項,繼承Thread類後需要重寫run方法並通過start方法啟動執行緒。 繼承Thread類耦合性太強了,因為java只能單繼承,所以不利

java:執行(實現Runnable的原理)方式的區別

* 1,看Thread類的建構函式,傳遞了Runnable介面的引用  * 2,通過init()方法找到傳遞的target給成員變數的target賦值 * 3,檢視run方法,發現run方法中有判斷,如果target不為null就會呼叫Runnable介面子類物件的run方法 *

java執行實現方法

          方法一:繼承Thread類,覆蓋方法run(), public class MyThread extends Thread { int count= 1, number; public MyThread(int num) { number = num;

建立Java執行的兩方式執行異常

一.使用多執行緒的兩種方法  使用多執行緒的兩種方法有:繼承Thread類和實現runable介面。 二.繼承Thread類 來看一下thread類的原始碼:  class Thread implements Runnable { 首先可以看出thread類也是實現Runable介面的run方法如下:

詳解建立Java執行的兩方式

      多執行緒的建立與使用是java工作學習中常見的內容,一直對多執行緒懷有神祕感,今天就把自己對多執行緒的理解分享給大家,供學習交流。       程序:程序(Process)是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業

c#使用執行方式示例詳解

(1)不需要傳遞引數,也不需要返回引數 ThreadStart是一個委託,這個委託的定義為void ThreadStart(),沒有引數與返回值。 複製程式碼程式碼如下: class Program { static void Main(string[] args)

java執行的兩方式

建立執行緒的第一種方法: class A extends Thread { public void run(){ while(true){ System.out.println("AAAAA

java停止執行方式

該學習筆記是學習《java多執行緒程式設計核心技術》高洪巖版本的第一章的學習筆記,在該章節中個人認為比較重要的是如何正確的停止一個執行緒。 停止一個執行緒最重要的是讓執行緒的run方法結束執行於是可以有以下幾種方法: 1.run方法結束完成

JAVA 建立執行方式

  1.繼承 Thread 類 2. 實現 Runnable 介面 3. ExecuteService、Callable<Class>、Future 有返回值執行緒 4. 執行緒池方式   一、繼承 Thread 類,建立執行緒類 (1)定義 Thr

當阿里面試官問我:Java建立執行方式?我就知道問題沒那麼簡單

這是最新的大廠面試系列,還原真實場景,提煉出知識點分享給大家。 點贊再看,養成習慣~ 微信搜尋【武哥聊程式設計】,關注這個 Java 菜鳥。 昨天有個小夥伴去阿里面試實習生崗位,面試官問他了一個老生常談的問題:你說一說 Java 建立執行緒都有哪些方式? 這哥們心中竊喜,這個老生常談的問題早已背的滾瓜爛熟

Java建立執行的4方式優缺點

目錄 1. 通過繼承Thread類實現 2. 通過實現Runnable介面實現 3. 通過lambda的方式實現 4. 通過Callable和Future建立執行緒  5. 通過繼承Thread類實現 程式碼展示  6. 通過實現Runnable介面實

Java執行-----實現生產者消費者模式的方式

   1 生產者消費者模式概述      生產者消費者模式就是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞佇列來進行通訊,所以生產者生產完資料之後不用等待消費者處理, 直接扔給阻塞佇列,消費者不找生產者要資料,

java 執行的一實現方式

private ThreadPoolExecutor threadPoolExecutor; /** * 獲取執行緒池 * @return */ private ThreadPoolExecutor getThreadPoolExecutor(){

[Java][實現執行的三方式]

目錄 本系列學習筆記簡介 多執行緒的繼承Thread類實現 程序執行緒簡介 多執行緒賣票介紹 程式碼塊 錯誤程式碼塊 正確程式碼塊

java實現執行的兩方式

Java需要併發控制三個原因: 多執行緒環境 存在共享資源 多個執行緒操作(修改)共享資源 下面分別用繼承Thread類和實現Runnable介面倆種方式實現併發控制, 繼承Thread類 繼承Thread類方式,最後建立物件是因為會是三個不同的執行緒物件,所以

Java執行之四實現方式

介紹 繼承Thread類,並重寫其run方法 實現Runnable介面 實現Callable介面通過FutureTask包裝器來建立Thread執行緒 執行緒池,使用ExecutorService、Callable、Future實現有返回結果的多執行緒。 其

java執行的三實現方式的極簡範例

java提供了三種多執行緒的實現方式,分別為:繼承Thread類、實現Runnable介面 和 實現Callable<>介面。 繼承Thread類 執行緒的執行體是run()方法,所以我們只需要過載父類的run()方法。建立類物件,呼叫start()

JAVA執行的四實現方式

1.繼承Thread  重寫run()方法,該run方法表示執行緒要完成的任務。建立執行緒物件,呼叫物件的start()方法來啟動執行緒。 2.Runnable介面 重寫介面中run方法。建立Runable例項類的例項,並依此例項作為Thread的target來建立Th

JAVA執行實現的四方式

         昨天自己用ExecutorService建立執行緒池做穿透測試了一下,感覺挺有意思,所以又好好的看了一下執行緒的問題,在此轉載了一篇博友的文章,感覺總結的不錯,所以分享一下. Java多執行緒實現方式主要有四種: 繼承Thread類、實現Runnable