【Java】面試題2、單線程與多線程;

本文主要回答3個問題:是什麼,爲什麼,怎麼弄?

1、線程是什麼?
附一段【百度百科】的介紹:

線程(英語:thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。在Unix System V及SunOS中也被稱爲輕量進程(lightweight processes),但輕量進程更多指內核線程(kernel thread),而把用戶線程(user thread)稱爲線程。

打個比方,一個系統中,類似於我們一個公司,每個人都是一個線程,人,就是公司分派任務的最小維度,最小單位,公司不能說,你的左手去打字,右手幫我衝一杯咖啡;這樣是不可以的(除非你很秀);進程就可以理解你們一個小組;

2、爲什麼要用線程;
線程主要講的就是多線程;一個人如果類比一個線程的話,多個人的工作團隊就是多線程;一個人的工作量,一般比不上多個人的工作量;提高整個系統的效率;注意,這裏不是提升單個線程的工作效率;我公司就我一個人,我啥都會,啥也知道,做一些簡單的工作肯定是我一個人效率高;但是如果多個人團隊協作;任務分配,溝通,爭奪資源(爭奪客戶,爭奪優先級),都是會有內耗的,對於一些簡單的工作,多線程的每個人的效率一般是低於一個人(理性人)工作的;多線程的優勢在於:

  1. 人多系統的力量大,速度快,衆人拾柴火焰高;
  2. 互相協助,共同承擔任務,減輕單個線程的壓力;
  3. 降低風險:防止一個線程的癱瘓造成整個系統癱瘓;(單線程:一人生病,系統癱瘓;多線程:每個人分擔一些,系統還能運行);

3、如何實現線程?
實現線程的方式有4中:

  1. 實現Runnable接口;
  2. 實現Callable接口;
  3. 繼承Thread類,然後new 出該線程;
  4. 線程池創建;

①、實現Runnable接口:

public class TestRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("實現Runnable接口");
    }
}

截圖:
在這裏插入圖片描述

運行該線程:
在這裏插入圖片描述

當然,你也可以直接new 一個Runnable接口,再實現,也是可以的;
在這裏插入圖片描述

②、實現Callable接口:
這裏,我們在這個線程中返回一個double類型的隨機數;

import java.util.concurrent.Callable;

public class CallableThread implements Callable {



    @Override
    public Object call() throws Exception {
        return Math.random();
    }
}

測試運行結果:
在這裏插入圖片描述

③、繼承Thread類,然後new出該新類;

public class TestExtendsThread extends Thread {

    @Override
    public void run() {
        System.out.println("繼承Thread類");
    }
}

測試運行結果:
在這裏插入圖片描述

④、使用線程池創建線程;

    @Test
    public void testThreadPool(){
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
        for(int i=0;i<5;i++){
            newFixedThreadPool.submit(new TestExtendsThread());
        }
    }

測試運行結果:
在這裏插入圖片描述

全部代碼如下:

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThread {
    
    /**
     * 測試繼承了Runnable接口的線程;
     */
    @Test
    void runable(){
//        TestRunnable testRunnable = new TestRunnable();
//        testRunnable.run();


        /**
         * 直接
         */
        new Runnable() {
            @Override
            public void run() {
                System.out.println("直接new 一個Runnable可運行接口,然後實現;");
            }
        }.run();
    }
    

    /**
     * 測試具有返回值的線程
     * @throws Exception 拋出異常
     */
    @Test
    void testCallable() throws Exception {
        CallableThread callableThread = new CallableThread();
        double  randomNum = (double)callableThread.call();
        System.out.println(randomNum);
    }

    /**
     * 測試繼承Thread類的線程
     * @throws Exception 拋出異常
     */
    @Test
    void testNewThread() throws Exception {
        TestExtendsThread thread = new TestExtendsThread();
        thread.start();
    }

    
    /**
     * 使用線程池創建線程;
     */
    @Test
    public void testThreadPool(){
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
        for(int i=0;i<5;i++){
            newFixedThreadPool.submit(new TestExtendsThread());
        }
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章