【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());
        }
    }


}

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