线程介绍

114 阅读2分钟

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

线程与进程

程序,进程,线程的区别

  • 程序:一段静态的代码

  • 进程:正在运行的程序。有生命周期

    • 系统会为进程分配资源
  • 线程:进程可进一步细化为线程,是程序内部执行的一条执行路线

    • 线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器
    • 一个java程序运行至少有三个线程:main线程,gc(垃圾回收)线程,异常处理线程

有很多单独运行的程序,每个程序有一个独立的进程。

进程想要执行任务就需要依赖线程。换句话说,就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。

java默认2个线程,1.main线程 2.gc线程

java是并行的,由一个CPU交替执行。由于速度太快,看不出来。

线程的方法

1.start() :启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行。如果当前CPU空闲,就会执行run方法

2.run()方法中为线程需要执行的方法

3.getName:获取名称

4.join()

5.yield():礼让线程,释放自己CPU,但不会释放同步锁,进入就绪状态。 但是进入就绪状态后还是会去抢夺锁,可能又获得了锁

6.interrupt() :中断线程,修改中断标志位为true,

实现多线程的方法

1.继承Thread类

2.实现Runnbale接口

1.创建类实现Runnable接口

2.实现run方法

3.创建Thread,将该类塞入Thread的参数

public static void main(String[] args) {
  new Thread(MyThread).start();   
}
​
class MyThread implements Runnable{
    @Ovrride
    public void run(){
        xxxxx
    }
}

3.实现Callable接口

1.有返回值

2.可以抛出异常

3.实现call方法,而不是run方法

泛型的参数就是返回异常的类型

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

选择String,那么call方法返回的类型就是String

public class myThread implements Callable<String> {
    @Override
    public String call() throws Exception {
        // 实现代码
        return "1";
    }
}

那么怎么能够调用callabel呢?

new Thread().start 参数只能是Runnnable类型,那么想要多线程,Callable就需要和Runnable搭上关系。

通过FutureTask是Runnbale的实现类勾搭上Runnable,FutureTask可以接收Callable参数

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
​
​
public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 这一个相当于Runnable ,将其放入Thread的参数
        FutureTask< String > futureTask = new FutureTask<>(new myThread());
        new Thread(futureTask,"A").start();
​
        // 获取Callable的返回结果
        String s = futureTask.get();
        System.out.println(s);
    }