八股文第九天

时间:2022年8月1日

什么是线程?线程和进程的区别?(了解)

线程:是进程的一个实体,是 cpu 调度和分派的基本单位,是比进程更小的可以独立运行的基本单位。

进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位。

特点:线程的划分尺度小于进程,这使多线程程序拥有高并发性,进程在运行时各自内存单元相互独立,线程之间内存共享,这使多线程编程可以拥有更好的性能和用户体验。

并发是指一个时间段中有几个程序都处于已启动到完毕之间,但任一个时刻点上只有一个程序在运行。

并行是指多个程序是在同一时刻点上是一起执行的。

创建线程有几种方式(必会)

1.继承 Thread 类并重写 run 方法创建线程,实现简单但不可以继承其他类

package com;

public class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread1 = " + i);
        }
    }
}
package com;

public class MyThread2 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread2 = " + i);
        }
    }
}
   @Test
    public void test1(){
        MyThread1 myThread1 = new MyThread1();
        MyThread2 myThread2 = new MyThread2();
        myThread1.start();
        myThread2.start();
    }

八股文第九天_第1张图片

2.实现 Runnable 接口并重写 run 方法。避免了单继承局限性,编程更加灵活,实 现解耦。

package com;

public class MyThread3 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread3 = " + i);
        }
    }
}
    @Test
    public void test2(){
        Thread thread = new Thread(new MyThread3());
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("test2 = " + i);
        }
    }

八股文第九天_第2张图片

3…实现 Callable 接口并重写 call 方法,创建线程。可以获取线程执行结果的返回 值,并且可以抛出异常。

package com;

import java.util.concurrent.Callable;

public class MyCallable implements Callable {
    @Override
    public Object call() throws Exception {

        for (int i = 0; i < 100; i++) {
            System.out.println("MyCallable = " + i);
        }
        return "s";
    }
}
    @Test
    public void test3() throws Exception {
        MyCallable callable = new MyCallable();
        FutureTask<Object> future = new FutureTask<>(callable);
        new Thread(future).start();
        for (int i = 0; i < 100; i++) {
            System.out.println("test3 = " + i);
        }
    }

八股文第九天_第3张图片

4.使用线程池创建(使用 java.util.concurrent.Executor 接口)

package com;

public class MyThreadPool implements Runnable {
    @Override
    public void run() {
        Thread thread = Thread.currentThread();
        System.out.println("线程池:" + thread.getName() + "访问网站");
    }
}
    @Test
    public void test4() throws Exception {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            threadPool.submit(new MyThreadPool());
        }
    }
    }

八股文第九天_第4张图片

Runnable 和 Callable 的区别?(必会)

主要区别:

  • Runnable 接口 run 方法无返回值;

  • Callable 接口 call 方法有返回值,支持泛型 Runnable 接口 run 方法只能抛出运行时异常,且无法捕获处理;Callable 接口 call 方法允许抛出异常,可以获取异常信息

如何启动一个新线程、调用 start 和 run 方法的区别?(必会)

八股文第九天_第5张图片

线程对象调用 run 方法不开启线程。仅是对象调用方法。

线程对象调用 start 开启线程,并让 jvm 调用 run 方法在开启的线程中执行调用 start 方法可以启动线程,并且使得线程进入就绪状态,而 run 方法只是 thread 的一 个普通方法,还是在主线程中执行。

线程有哪几种状态以及各种状态之间的转换?(必会)

  1. 第一是 new->新建状态。在生成线程对象,并没有调用该对象的 start 方法,这是线程处于 创建状态。

  2. 第二是 Runnable->就绪状态。当调用了线程对象的 start 方法之后,该线程就进入了就绪 状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。

  3. 第三是 Running->运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线 程就进入了运行状态,开始运行 run 函数当中的代码。

  4. 第四是阻塞状态。阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止运行。直到线程 进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

 (1)等待 – 通过调用线程的 wait() 方法,让线程等待某工作的完成。
  
 (2)超时等待 – 通过调用线程的 sleep() 或 join()或发出了 I/O 请求时,线程会进入到阻塞状态。 当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状 态。
 
 (3)同步阻塞 – 线程在获取 synchronized 同步锁失败(因为锁被其它线程所占用),它会进入同 步阻塞状态。 
  1. 第五是 dead->死亡状态: 线程执行完了或者因异常退出了 run()方法,该线程结束生命周期.

八股文第九天_第6张图片

你可能感兴趣的:(#,八股文大全,java,jvm,开发语言)