Concurrency (一) prac1.

weixin_34308389發表於2019-03-03
12673793-cd6da04314b94ea3.jpg
Concurrency.jpg

併發多執行緒Demo清單

1.定義任務,定義一個任務顯示發射之前的倒數計時


package com.lhsjohn.comcurrency.prac;

public class LiftOff implements Runnable {

    protected int countDown = 10;
    private static int taskCount = 0;
    private final int id = taskCount++;
    
    public LiftOff() {};
    public LiftOff(int countDown) {
        this.countDown = countDown;
    }
    
    public String status() {
        return "#" +id+"("+(countDown > 0?countDown:"liftOff")+"),";
    }

    @Override
    public void run() {
        while(countDown-->0) {
            System.out.println(status());
            Thread.yield();
        }
    }

}



識別符號id可以用來區分任務的多個例項,因為它是final的,一旦被初始化後就不希望被修改。
在run()中對靜態方法Thread.yield()的呼叫是對執行緒排程器的一種建議,它是Java執行緒機制的一部分,可以將CPU從一個執行緒轉移給另外一個執行緒。

2.MainThrad.java

package com.lhsjohn.comcurrency.prac;

public class MainThread {

      public static void main(String[] args) {
        LiftOff launch = new LiftOff();
        launch.run();
    }
}


執行結果:

#0(9),
#0(8),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#0(2),
#0(1),
#0(liftOff),


這裡的run()不是由單獨的執行緒驅動的,它是在main()中直接呼叫的,使用了分配給main()的那個執行緒
記住:要實現執行緒行為,你必須顯式地將一個任務附著到執行緒上。

3.下面展示如何用Thread來驅動LiftOff物件

package com.lhsjohn.comcurrency.prac;

public class BasicThreads {
   
    public static void main(String[] args) {
        Thread t = new Thread(new LiftOff());
        t.start();
        System.out.println("Waiting for LiftOff");
    }
}


輸出結果:

Waiting for LiftOff
#0(9),
#0(8),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#0(2),
#0(1),
#0(liftOff),

在這裡我們可以看到,Waiting for LiftOff訊息在倒數計時完成之前就出現了,這是因為我們產生的是對LiftOff.run()的方法的呼叫,並且這個方法還沒有完成,是因為這個方法是有不同的執行緒執行的,所以我們依舊可以進行main()執行緒中的其他操作。(任何執行緒都可以啟動其他執行緒)

4.新增更多執行緒驅動更多工

package com.lhsjohn.comcurrency.prac;

public class MoreBasicThreads {
    public static void main(String[] args) {
        
        for(int i=0;i<5;i++) {
            new Thread(new LiftOff()).start();
        }
        System.out.println("Waiting for Liftoff!!");
    }
}


輸出結果:

#0(9),
#0(8),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#4(9),
#4(8),
#4(7),
#2(9),
#3(9),
#1(9),
Waiting for Liftoff!!
#1(8),
#3(8),
#2(8),
#4(6),
#0(2),
#4(5),
#2(7),
#3(7),
#1(7),
#3(6),
#2(6),
#4(4),
#0(1),
#0(liftOff),
#4(3),
#2(5),
#3(5),
#3(4),
#3(3),
#3(2),
#3(1),
#3(liftOff),
#1(6),
#1(5),
#2(4),
#4(2),
#4(1),
#4(liftOff),
#2(3),
#1(4),
#2(2),
#1(3),
#2(1),
#1(2),
#2(liftOff),
#1(1),
#1(liftOff),


輸出說明不同任務的執行線上程被換進換出時混在了一起。這種交換是由執行緒排程器自動控制的。

這個程式一次執行的結果可能和另一次執行的結果不同,因為執行緒排程機制是非確定性的。

5.使用CachedThreadPool為每個任務都建立一個執行緒

package com.lhsjohn.comcurrency.prac;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPool {
  
    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for(int i = 0;i<5;i++) {
            exec.execute(new LiftOff());
            
        }
        exec.shutdown();
    } 
    
}



輸出結果:


#1(9),
#0(9),
#0(8),
#2(9),
#2(8),
#4(9),
#4(8),
#3(9),
#4(7),
#4(6),
#4(5),
#4(4),
#2(7),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#0(2),
#0(1),
#1(8),
#0(liftOff),
#2(6),
#4(3),
#3(8),
#4(2),
#4(1),
#4(liftOff),
#2(5),
#1(7),
#2(4),
#3(7),
#3(6),
#3(5),
#3(4),
#3(3),
#3(2),
#3(1),
#3(liftOff),
#2(3),
#1(6),
#2(2),
#1(5),
#2(1),
#1(4),
#2(liftOff),
#1(3),
#1(2),
#1(1),
#1(liftOff),


6.使用 FixedThreadPool使用有限執行緒集執行所提交的任務


package com.lhsjohn.comcurrency.prac;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPool {
    
    public static void main(String[] args) {
        ExecutorService exec = Executors.newFixedThreadPool(5);
        for(int i = 0; i<5; i++) {
            exec.execute(new LiftOff());
        }
        exec.shutdown();
    }
}


執行結果:

#1(9),
#4(9),
#3(9),
#2(9),
#0(9),
#2(8),
#3(8),
#1(8),
#4(8),
#1(7),
#3(7),
#2(7),
#0(8),
#2(6),
#3(6),
#1(6),
#4(7),
#1(5),
#3(5),
#2(5),
#0(7),
#2(4),
#3(4),
#1(4),
#4(6),
#1(3),
#3(3),
#2(3),
#0(6),
#2(2),
#3(2),
#1(2),
#4(5),
#1(1),
#3(1),
#2(1),
#0(5),
#2(liftOff),
#3(liftOff),
#1(liftOff),
#4(4),
#0(4),
#4(3),
#0(3),
#4(2),
#0(2),
#4(1),
#0(1),
#4(liftOff),
#0(liftOff),


通過FixedThreadPool 我們可以一次性預先執行代價高昂的執行緒分配,因而可以限制執行緒的數量了。

7.使用SingleThreadExector可以讓多個任務進行排隊

package com.lhsjohn.comcurrency.prac;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadExecutor {

     public static void main(String[] args) {
        ExecutorService exec = Executors.newSingleThreadExecutor();
        for(int i = 0;i<5;i++) {
            exec.execute(new LiftOff());
        }
        exec.shutdown();
    }
}


執行結果


#0(9),
#0(8),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#0(2),
#0(1),
#0(liftOff),
#1(9),
#1(8),
#1(7),
#1(6),
#1(5),
#1(4),
#1(3),
#1(2),
#1(1),
#1(liftOff),
#2(9),
#2(8),
#2(7),
#2(6),
#2(5),
#2(4),
#2(3),
#2(2),
#2(1),
#2(liftOff),
#3(9),
#3(8),
#3(7),
#3(6),
#3(5),
#3(4),
#3(3),
#3(2),
#3(1),
#3(liftOff),
#4(9),
#4(8),
#4(7),
#4(6),
#4(5),
#4(4),
#4(3),
#4(2),
#4(1),
#4(liftOff),



8.實現一個Runnable 。在run()內部列印一條訊息,然後呼叫yield()。重複這個操作三次,然後從run中返回。在構造器中放置一條啟動訊息,並且放置一條在任務終止時的關閉的訊息。使用執行緒建立大量的這種任務並驅動它們。

package com.lhsjohn.comcurrency.prac;

class Ex1RunnerA implements Runnable{

    public Ex1RunnerA() {
        System.out.println("Constructing Ex1RunnerA");
    }
    
    @Override
    public void run() {
        for(int i = 0 ;i<3;i++) {
            System.out.println("Hi from Ex1RunnerA");
            Thread.yield();
        }
        System.out.println("Ex1RunnerA task complete");
        return;
    }
    
    
        
}

class Ex1RunnerB implements Runnable{

    public Ex1RunnerB() {
        System.out.println("Constructing Ex1RunnerB");
    }
    
    @Override
    public void run() {
        for(int i = 0 ;i<3;i++) {
            System.out.println("Hi from Ex1RunnerB");
            Thread.yield();
        }
        System.out.println("Ex1RunnerB task complete");
        return;
    }
            
}


class Ex1RunnerC implements Runnable{

    public Ex1RunnerC() {
        System.out.println("Constructing Ex1RunnerC");
    }
    
    @Override
    public void run() {
        for(int i = 0 ;i<3;i++) {
            System.out.println("Hi from Ex1RunnerC");
            Thread.yield();
        }
        System.out.println("Ex1RunnerC task complete");
        return;
    }
    
}


public class Ex1 {

      public static void main(String[] args) {
        Thread ta = new Thread(new Ex1RunnerA());
        Thread tb = new Thread(new Ex1RunnerB());
        Thread tc = new Thread(new Ex1RunnerC());
        ta.start();
        tb.start();
        tc.start();
    }
    
    
}


執行結果

Constructing Ex1RunnerA
Constructing Ex1RunnerB
Constructing Ex1RunnerC
Hi from Ex1RunnerB
Hi from Ex1RunnerB
Hi from Ex1RunnerB
Ex1RunnerB task complete
Hi from Ex1RunnerA
Hi from Ex1RunnerC
Hi from Ex1RunnerA
Hi from Ex1RunnerA
Ex1RunnerA task complete
Hi from Ex1RunnerC
Hi from Ex1RunnerC
Ex1RunnerC task complete

9建立一個任務,它可以產生由n個斐波那契數字組成的序列,其中n是由任務的構造器而提供的。使用執行緒建立大量的這種任務並驅動它們。

package com.lhsjohn.comcurrency.prac;


class Ex2FibonacciA implements Runnable{
  
    private int n = 0;
    public Ex2FibonacciA(int n) {
       this.n = n;
    }
    
    public int fib(int x) {
        if(x<2) return 1;
        return fib(x-2) + fib(x-1);
    }

    @Override
    public void run() {
        for(int i=0; i<n; i++) {
            System.out.println(fib(i));
        }   
    }
    
}

class Ex2FibonacciB implements Runnable{
      
    private int n = 0;
    public Ex2FibonacciB(int n) {
       this.n = n;
    }
    
    public int fib(int x) {
        if(x<2) return 1;
        return fib(x-2) + fib(x-1);
    }

    @Override
    public void run() {
        for(int i=0; i<n; i++) {
            System.out.println(fib(i));
        }   
    }
    
}

class Ex2FibonacciC implements Runnable{
      
    private int n = 0;
    public Ex2FibonacciC(int n) {
       this.n = n;
    }
    
    public int fib(int x) {
        if(x<2) return 1;
        return fib(x-2) + fib(x-1);
    }

    @Override
    public void run() {
        for(int i=0; i<n; i++) {
            System.out.println(fib(i));
        }   
    }
    
}

class Ex2FibonacciD implements Runnable{
      
    private int n = 0;
    public Ex2FibonacciD(int n) {
       this.n = n;
    }
    
    public int fib(int x) {
        if(x<2) return 1;
        return fib(x-2) + fib(x-1);
    }

    @Override
    public void run() {
        for(int i=0; i<n; i++) {
            System.out.println(fib(i));
        }   
    }
    
}


public class Ex2 {
     
    public static void main(String[] args) {
        Thread f1 = new Thread(new Ex2FibonacciA(15));
        Thread f2 = new Thread(new Ex2FibonacciB(15));
        Thread f3 = new Thread(new Ex2FibonacciC(15));
        Thread f4 = new Thread(new Ex2FibonacciD(15));
        f1.start();
        f2.start();
        f3.start();
        f4.start();
    }
}


輸出結果:


1123581321341121123581321341123581321345555891442333773610558958132134558989144233144233144233377377377610610610

10.使用不同型別的執行器重複練習8


package com.lhsjohn.comcurrency.prac;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Ex3RunnerA implements Runnable{

    public Ex3RunnerA() {
      System.out.println("Constructing Ex3RunnerA...");
    }
    
    @Override
    public void run() {
        for(int i = 0; i<3;i++) {
           System.out.println("Hi Ex3RunnerA!");
           Thread.yield();
        }
      return;
    }
    
}

class Ex3RunnerB implements Runnable{

    public Ex3RunnerB() {
      System.out.println("Constructing Ex3RunnerB...");
    }
    
    @Override
    public void run() {
        for(int i = 0; i<3;i++) {
           System.out.println("Hi Ex3RunnerB!");
           Thread.yield();
        }
      return;
    }
    
}

class Ex3RunnerC implements Runnable{

    public Ex3RunnerC() {
      System.out.println("Constructing Ex3RunnerC...");
    }
    
    @Override
    public void run() {
        for(int i = 0; i<3;i++) {
           System.out.println("Hi Ex3RunnerC!");
           Thread.yield();
        }
        return;
    }
}

public class Ex3 {
    
    public static void main(String[] args) {
        ExecutorService exec1 = Executors.newCachedThreadPool();
        exec1.execute(new Ex3RunnerA());
        exec1.execute(new Ex3RunnerB());
        exec1.execute(new Ex3RunnerC());
        exec1.shutdown();
        
        ExecutorService exec2 = Executors.newFixedThreadPool(3);
        exec2.execute(new Ex3RunnerA());
        exec2.execute(new Ex3RunnerB());
        exec2.execute(new Ex3RunnerC());
        exec2.shutdown();
        
        ExecutorService exec3 = Executors.newSingleThreadExecutor();
        exec3.execute(new Ex3RunnerA());
        exec3.execute(new Ex3RunnerB());
        exec3.execute(new Ex3RunnerC());
        exec3.shutdown();

    }
}



輸出結果:


Constructing Ex3RunnerA...
Hi Ex3RunnerA!
Hi Ex3RunnerA!
Hi Ex3RunnerA!
Constructing Ex3RunnerB...
Hi Ex3RunnerB!
Hi Ex3RunnerB!
Hi Ex3RunnerB!
Constructing Ex3RunnerC...
Hi Ex3RunnerC!
Hi Ex3RunnerC!
Hi Ex3RunnerC!
Constructing Ex3RunnerA...
Constructing Ex3RunnerB...
Hi Ex3RunnerA!
Hi Ex3RunnerA!
Hi Ex3RunnerA!
Constructing Ex3RunnerC...
Hi Ex3RunnerB!
Hi Ex3RunnerB!
Hi Ex3RunnerB!
Hi Ex3RunnerC!
Hi Ex3RunnerC!
Hi Ex3RunnerC!
Constructing Ex3RunnerA...
Constructing Ex3RunnerB...
Constructing Ex3RunnerC...
Hi Ex3RunnerA!
Hi Ex3RunnerA!
Hi Ex3RunnerA!
Hi Ex3RunnerB!
Hi Ex3RunnerB!
Hi Ex3RunnerB!
Hi Ex3RunnerC!
Hi Ex3RunnerC!
Hi Ex3RunnerC!


11.使用不同型別的執行器重複練習9


package com.lhsjohn.comcurrency.prac;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Ex4FibonacciA implements Runnable{
    private int n = 0;
    public Ex4FibonacciA(int n) {
        this.n = n ;
    }
    
    public int fib(int x) {
        if(x<2)  return 1;
        return fib(x-2) + fib(x-1);
    }
    
    @Override
    public void run() {
        for(int i=0;i<n;i++) {
            System.out.println(fib(i));
        }
    }
    
}

class Ex4FibonacciB implements Runnable{
    private int n = 0;
    
    public Ex4FibonacciB(int n) {
        this.n = n ;
    }
    
    public int fib(int x) {
        if(x<2)  return 1;
        return fib(x-2) + fib(x-1);
    }
    
    @Override
    public void run() {
        for(int i=0;i<n;i++) {
            System.out.println(fib(i));
        }
    }
    
}

class Ex4FibonacciC implements Runnable{
    private int n = 0;
    
    public Ex4FibonacciC(int n) {
        this.n = n ;
    }
    
    public int fib(int x) {
        if(x<2)  return 1;
        return fib(x-2) + fib(x-1);
    }
    
    @Override
    public void run() {
        for(int i=0;i<n;i++) {
            System.out.println(fib(i));
        }
    }
    
}

class Ex4FibonacciD implements Runnable{
    private int n = 0;
    
    public Ex4FibonacciD(int n) {
        this.n = n ;
    }
    
    public int fib(int x) {
        if(x<2)  return 1;
        return fib(x-2) + fib(x-1);
    }
    
    @Override
    public void run() {
        for(int i=0;i<n;i++) {
            System.out.println(fib(i));
        }
    }
    
}


public class Ex4 {
    public static void main(String[] args) {
        ExecutorService exec1 = Executors.newCachedThreadPool();
        exec1.execute(new Ex4FibonacciA(15));
        exec1.execute(new Ex4FibonacciB(15));
        exec1.execute(new Ex4FibonacciC(15));
        exec1.execute(new Ex4FibonacciD(15));
        exec1.shutdown();
        
        
        
        ExecutorService exec2 = Executors.newFixedThreadPool(4);
        exec2.execute(new Ex4FibonacciA(15));
        exec2.execute(new Ex4FibonacciB(15));
        exec2.execute(new Ex4FibonacciC(15));
        exec2.execute(new Ex4FibonacciD(15));
        exec2.shutdown();
        
        
        ExecutorService exec3 = Executors.newSingleThreadExecutor();
        exec3.execute(new Ex4FibonacciA(15));
        exec3.execute(new Ex4FibonacciB(15));
        exec3.execute(new Ex4FibonacciC(15));
        exec3.execute(new Ex4FibonacciD(15));
        exec3.shutdown();
    
        
    }
    
    
    
}



輸出結果:略 見上面

作者: lhsjohn

相關文章