JAVA 多執行緒總結(一)

b10l07發表於2017-11-01
  • 在網上查詢了很多關於java多執行緒的知識,各位大牛對java 多執行緒的講解和到位,我在這裡主要是對大牛技術貼做一些自己的總結。

執行緒和程式

  • 我們在討論多執行緒的問題時,必然離不開區分程式和執行緒的話題,那什麼是執行緒和程式?

在網上找了一個比較權威的解釋:

程式是一個具有一定獨立功能的程式在一個資料集上的一次動態執行的過程,是作業系統進行資源分配和排程的一個獨立單位,是應用程式執行的載體。

程式是能擁有資源和獨立執行的最小單位,也是程式執行的最小單位。

其實用文字解釋還是挺不好懂的,可以參考看看程式設計思想之多執行緒與多程式(1)——以作業系統的角度述說執行緒與程式這篇文章是講得比較清楚的,我在這裡就不多做詳述了。

多執行緒的幾種形式

  • 繼承Thread類
public class myThread extends Thread {

    @Override
    public void run() {
        super.run();
    }
}
  • 實現Runnable介面
public class myThread implements Runnable {

    @Override
    public void run() {
        
    }
}

其實這兩種方式沒有本質的區別,最終都會實現Runnable介面。

例子

  • basket.java
public class Basket {

    private int index = 0;

    private ManTou[] manTous = new ManTou[10];

    public synchronized void push(ManTou manTou){
        while (index == manTous.length){
            try{
                System.out.println("籃子滿了");
                this.wait();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        System.out.println(Thread.currentThread().getName()+"生產"+manTou.toString());
        this.notify();
        manTous[index] = manTou;
        index++;
    }

    public synchronized ManTou pop(){
        while (index == 0){
            try {
                System.out.println("籃子空了");
                this.wait();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        System.out.println(Thread.currentThread().getName()+"吃了"+manTous.toString());
        ManTou manTou = manTous[--index];
        this.notify();
        return manTou;
    }
}

basket 裡面主要是兩個方法:push和pop,實現了對籃子的兩個動作。

  • ManTou.java
public class ManTou {

    private int id;

    public ManTou(int id){
        this.id = id;
    }

    @Override
    public String toString() {
        return "ManTou{" +
                "id=" + id +
                '}';
    }
}

ManTou.java 定義了饅頭的特性

  • Consumer.java
public class Consumer implements Runnable {

    public Basket basket;

    public Consumer(Basket basket){
        this.basket = basket;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            ManTou manTou = basket.pop();
            try {
                Thread.sleep(500);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

消費者這邊實現了一個從籃子裡面拿走饅頭的動作

  • Producer.java
public class Producer implements Runnable {

    private Basket basket;

    public Producer(Basket basket){
        this.basket = basket;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            ManTou manTou = new ManTou(i);
            basket.push(manTou);

            try {
                Thread.sleep(500);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

同樣Producer也實現了一個將饅頭裝載到籃子的過程。

  • main.java
public class ProducerConsumer {

    public static void main(String[] args){

        Basket basket = new Basket();

        new Thread(new Producer(basket)).start();

        new Thread(new Consumer(basket)).start();
    }
}

結果

Thread-0生產ManTou{id=0}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=1}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=2}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=3}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=4}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=5}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=6}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=7}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=8}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=9}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=10}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=11}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=12}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=13}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=14}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=15}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=16}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=17}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=18}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生產ManTou{id=19}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1

這是簡單的學習了java 多執行緒的知識,初步瞭解了多執行緒的工作原理。

相關文章