Java中的多執行緒學習筆記001:Thread類和Runnable介面
阿新 • • 發佈:2020-12-01
https://space.bilibili.com/95256449/channel/detail?cid=146244
Java中的多執行緒001
1、繼承Thread類,重寫run方法,建立執行緒物件,呼叫start()方法
package com.stark.study; //建立執行緒方式一:繼承Thread類,重寫run()方法,呼叫start()開啟執行緒 public class TestThread extends Thread { //重寫run方法 @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("副執行緒" + i); } } //main執行緒,主執行緒 public static void main(String[] args) { //建立執行緒物件 TestThread testThread = new TestThread(); //呼叫start()方法啟動副執行緒 testThread.start(); for (int i = 0; i < 1000; i++) { System.out.println("主執行緒" + i); } } }
2、使用Apache的commons io 和多執行緒下載圖片
package com.stark.study; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; //練習Thread,實現多執行緒同步下載圖片 public class TestThread2 extends Thread { private String url;//網路地址 private String name;//儲存的檔名 public TestThread2(String url,String name) { this.url = url; this.name = name; } //重寫run方法 @Override public void run() { // super.run(); WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url,name); System.out.println(name + "檔案已下載"); } public static void main(String[] args) { TestThread2 t1 = new TestThread2("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","picture001.jpg"); TestThread2 t2 = new TestThread2("https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/[email protected]","picture002.jpg"); TestThread2 t3 = new TestThread2("https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/[email protected]","picture003.jpg"); t1.start(); t2.start(); t3.start(); } } class WebDownloader { //從網頁下載圖片的方法 public void downloader(String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO異常,WebDownloader.downloader()方法異常。"); } } }
3、 建立執行緒的另一種方法是宣告一個實現Runnable介面的類。 該類然後實現run方法。 然後可以分配類的例項,再建立Thread時作為引數傳遞,然後啟動。
package com.stark.study; //建立執行緒方式2:實現Runnable介面,重寫run方法, 然後可以分配類的例項,再建立Thread時作為引數傳遞,然後啟動。 public class TestThread3 implements Runnable { //重寫run方法 @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("副執行緒" + i); } } //main執行緒,主執行緒 public static void main(String[] args) { //建立Runnable介面的實現類物件 TestThread3 testThread3 = new TestThread3(); //建立Thread類的物件,將Runnable的實現類物件作為引數傳入,然後啟動執行緒 // Thread thread = new Thread(testThread3); // thread.start(); new Thread(testThread3).start(); for (int i = 0; i < 1000; i++) { System.out.println("主執行緒" + i); } } }
4、 多執行緒操作同一個物件,執行緒不安全,存在併發問題
package com.stark.study;
//多個執行緒同時操作同一個物件
//買火車票的例子
//多個執行緒操作同一個物件時,執行緒不安全,資料紊亂,存在併發問題
public class TestThread4 implements Runnable {
//票數
private int ticketNums = 30;
@Override
public void run() {
while (true)
{
if (0 >= ticketNums)
{
break;
}
System.out.println(Thread.currentThread().getName() + "--拿到了第" + ticketNums-- + "票");
//延時
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TestThread4 ticket = new TestThread4();
//多執行緒操作同一個物件
new Thread(ticket,"學生").start();
new Thread(ticket,"老師").start();
new Thread(ticket,"黃牛").start();
}
}
5、 龜兔賽跑
package com.stark.study;
public class Race implements Runnable {
private static String winner;//勝利者
@Override
public void run() {
for (int i = 0; i <= 1000; i++) {
//判斷比賽是否結束
boolean flag = gameOver(i);
if (flag){
break;
}
//模擬兔子休息
if (Thread.currentThread().getName().equals("兔子") && (i%10 == 0)){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "--跑了" + i + "步");
}
}
//判斷是否完成比賽
private boolean gameOver(int steps) {
//判斷是否有勝利者
if (null != winner) {
return true;
}
if (steps >= 1000){
winner = Thread.currentThread().getName();
System.out.println("Winner is " + winner );
return true;
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"烏龜").start();
}
}