Java線程的建立

Java線程的建立

Thread類

  • 自定義線程繼承類Thread類
  • 重寫run()方法,編寫線程執行體
  • 建立線程對象,調用start()方法啓動線程

注意:線程不必定當即執行,CPU安排調度java

package com.cnblogs.thread;

//建立線程方式一:繼承Thread類,重寫run()方法,調用start開啓線程
public class TestThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("看代碼中。。。");
        }
    }
/*
線程開啓不必定當即執行,由cpu調度執行
 */
    public static void main(String[] args) {
        //建立一個線程對象
        TestThread testThread1 = new TestThread();
        testThread1.start();
//兩個線程交替執行
        for (int i = 0; i < 1000; i++) {
            System.out.println("俺在學習多線程!!!");
        }
    }
}

Runnable接口

  • 定義MyRunnable類實現Runnable接口
  • 實現run()方法,編寫線程執行體
  • 建立線程對象,調用start()方法啓動線程

推薦使用Runnable對象,由於Java單繼承的侷限性web

package com.cnblogs.thread;
//建立線程方式二:實現runnable接口,重寫run方法,執行線程須要丟入runnable接口實現類,調用start方法
public class TestThread3 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("看代碼中。。。");
        }
    }

    public static void main(String[] args) {
        //建立runnable接口的實現類對象
        TestThread3 testThread3 = new TestThread3();
        //建立線程對象,經過線程對象來開啓咱們的線程,代理
//        Thread thread = new Thread();
//        thread.start();

        //簡寫
        new Thread(testThread3).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("俺在學習多線程!!!");
        }
    }
}

小結

  • 繼承Thread類apache

    • 子類繼承Thread類具有多線程能力
    • 啓動線程:子類對象.start()
    • 不建議使用:避免OOP單繼承侷限性
  • 繼承Runnable接口網絡

    • 實現接口Runnable具備多線程能力
    • 啓動線程:傳入目標對象+Thread對象.start()
    • 推薦使用:避免單繼承侷限性,靈活方便,方便同一個對象被多個線程使用

案例1:龜兔賽跑

  1. 首先來個賽道距離,而後要離終點愈來愈近
  2. 判斷比賽是否結束
  3. 打印出勝利者
  4. 龜兔賽跑開始
  5. 故事中是烏龜贏得,兔子須要睡覺,咱們須要模擬兔子隨機
  6. 終於,烏龜贏得比賽
package com.cnblogs.thread;

//模擬龜兔賽跑
public class Race implements Runnable{

    private static String winner;
    
    @Override
    public void run() {

        for (int i = 0; i <= 1000; i++) {
            //給兔子加延時,模擬睡覺
            if(Thread.currentThread().getName().equals("兔子") && i % 10 == 0){
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            boolean flag = gameOver(i);
            if(flag){
                break;
            }
            System.out.println(Thread.currentThread().getName() + "跑了" + i + "步!");
        }
    }

    private boolean gameOver(int step){
        if(winner != null){
            return true;
        }else{
            if(step >= 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();
    }
}

案例2:下載網圖(須要導入commons包)

package com.cnblogs.thread;

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;
    }

    @Override
    public void run() {
        WebDownLoader webDownLoader = new WebDownLoader();
        webDownLoader.downloader(url,name);
        System.out.println("下載了文件名爲:" + name + "的文件");
    }

    public static void main(String[] args) {
        TestThread2 t1 = new TestThread2("https://img-blog.csdnimg.cn/2021051913555284.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg4NDIzNA==,size_16,color_FFFFFF,t_70","1.jpg");
        TestThread2 t2 = new TestThread2("https://img-blog.csdnimg.cn/20210519135426133.png","2.jpg");
        TestThread2 t3 = new TestThread2("https://img-blog.csdnimg.cn/20210519135102589.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg4NDIzNA==,size_16,color_FFFFFF,t_70","3.jpg");

        t1.start();
        t2.start();
        t3.start();
        /*
        下載了文件名爲:2.jpg的文件
        下載了文件名爲:3.jpg的文件
        下載了文件名爲:1.jpg的文件
         */
    }
}

class WebDownLoader{
    public void downloader(String url , String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            System.out.println("IO異常,downloader方法出現問題!");
            e.printStackTrace();
        }
    }
}

線程池建立線程

ExecutorService:用來存儲線程的池子,把新建線程/啓動線程/關閉線程的任務都交給池來管理多線程

  • execute(Runnable任務對象) 把任務丟到線程池

Executors 輔助建立線程池的工具類ide

  • newFixedThreadPool(int nThreads) 最多n個線程的線程池
  • newCachedThreadPool() 足夠多的線程,使任務沒必要等待
  • newSingleThreadExecutor() 只有一個線程的線程池
package com.cnblogs;

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

public class TestRunnable {

    public static void main(String[] args) {
        MyRunnable target = new MyRunnable();
        //建立線程池
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            pool.execute(target);
        }

    }
}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("多線程哦!!" + Thread.currentThread().getName());
        }
    }
}
相關文章
相關標籤/搜索