Concurrency (一) prac1.
併發多執行緒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
相關文章
- Concurrency(一:如何理解多執行緒)執行緒
- Concurrency Patterns in GoGo
- Asyncio in Python and Concurrency tasksPython
- Java Concurrency in Depth - 1Java
- Java Concurrency in Depth - 2Java
- Concurrency(十一: 飢餓與公平)
- Concurrency(四:執行緒安全)執行緒
- Concurrency(六: 同步程式碼塊)
- Concurrency(五: Java記憶體模型)Java記憶體模型
- Concurrency(十五: Java中的讀寫鎖)Java
- 聊聊FluxFlatMap的concurrency及prefetch引數UX
- MySQL:一個innodb_thread_concurrency設定不當引發的故障MySqlthread
- 用 Go 語言實戰 Limit Concurrency 方法GoMIT
- Oracle 19c Concepts(09):Data Concurrency and ConsistencyOracle
- Concurrency(二:建立和啟動執行緒)執行緒
- Go基礎學習六之併發concurrencyGo
- Concurrency(二十三: 非阻塞演算法下)演算法
- Concurrency(二十二: 非阻塞演算法上)演算法
- Concurrency(三:競態條件和臨界區)
- C++ concurrency::task實現非同步程式設計(WindowsC++非同步程式設計Windows
- cmu15545筆記-併發控制總結(Concurrency Control Summary)筆記
- MySQL 8.0 Reference Manual(讀書筆記73節--Thread Concurrency for InnoDB and I/O Threads)MySql筆記thread
- 理解真實專案中的 Go 併發 Bug(Understanding Real-World Concurrency Bugs in Go)Go
- MDN之JavaScript-高階(二)【Concurrency model and Event Loop併發模型與事件迴圈】JavaScriptOOP模型事件
- 【譯】kotlin 協程官方文件(8)-共享可變狀態和併發性(Shared mutable state and concurrency)Kotlin
- CMU15-455 Lab2 - task4 Concurrency Index -併發B+樹索引演算法的實現Index索引演算法
- 每日一練(一)
- 一筆一劃教你寫一簽名
- 一次一密
- 一條唯一索引索引
- 一步一步實現一個PromisePromise
- Mysql 一主一從配置MySql
- 一、JVM專欄之一JVM
- 一比一還原axios原始碼(一)—— 發起第一個請求iOS原始碼
- MyBatis 使用resultMap 以及 一對一和一對多MyBatis
- 一杯茶,一支菸,一行程式碼寫一天 !行程
- 一對一直播原始碼助力一對一教育,進入直播3.0時代!原始碼
- L1-030 一幫一