程序员

高频面试题,java线程的三种创建方式与六种状态,一次性帮你搞定

2020-08-04  本文已影响0人  程序员伟杰

前言

在JAVA中,用Thread类代表线程,所有线程对象,都必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行一段顺序执行的代码,JAVA使用线程执行体来容纳这段代码。所以,我们创建线程时,主要是根据实际需求,编写放入线程执行体的代码。

三种创建方式

一、通过继承Thread类创建线程

//MyThread继承Thread类
public class MyThread extends Thread {
    //重写run方法
    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 10; i++) {
            //获取当前线程名字并且打印出来
            System.out.println(Thread.currentThread().getName() + "  " + i);
        }

    }
}

    public static void main(String[] args) {
        //创建子线程对象
        MyThread myThread = new MyThread();
        //给线程跟新名字
        myThread.setName("MyThread");
        //启动线程
        myThread.start();
    }

//运行结果
MyThread  0
MyThread  1
MyThread  2
MyThread  3
MyThread  4
MyThread  5
MyThread  6
MyThread  7
MyThread  8
MyThread  9

二、通过实现Runable接口创建线程

//创建MyRunnable类实现Runnable接口
public class MyRunnable implements Runnable {
    // 实现run()方法
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            // 获取当前线程名字并打印出来
            System.out.println(Thread.currentThread().getName() + "  " + i);
        }
    }

}

    public static void main(String[] args) {
        //创建MyRunnable类的对象
        MyRunnable myRunnable = new MyRunnable();
        //创建子线程,并且重命名
        Thread thread = new Thread(myRunnable,"myRunnable");
        //启动子线程
        thread.start();
    }

//运行结果
myRunnable  0
myRunnable  1
myRunnable  2
myRunnable  3
myRunnable  4
myRunnable  5
myRunnable  6
myRunnable  7
myRunnable  8
myRunnable  9

三、通过实现Callable接口来创建接口

//MyThread继承Thread类
public class MyThread extends Thread {
    //重写run方法
    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 10; i++) {
            //获取当前线程名字并且打印出来
            System.out.println(Thread.currentThread().getName() + "  " + i);
        }

    }
}

    public static void main(String[] args) {
        // 创建MyCallable对象
        MyCallable myCallable = new MyCallable();
        // 使用FutureTask来包装myCallable对象,
        // FutureTask类封装了myCallable对象call()方法的返回值
        // 这里设置泛型的类型必须和myCallable的返回值类型一致
        FutureTask<Integer> futureTask = new FutureTask<Integer>(myCallable);
        // 创建子线程并给线程重命名
        Thread thread = new Thread(futureTask, "myCallable");
        // 启动子线程
        thread.start();
        try {
            // 在子线程执行完毕以后,通过futureTask来调用get()方法获取返回值
            Integer integer = futureTask.get();
            System.out.println(integer);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

//运行结果
myCallable  0
myCallable  1
myCallable  2
myCallable  3
myCallable  4
myCallable  5
myCallable  6
myCallable  7
myCallable  8
myCallable  9
sum=45

三种创建线程的方式中通过实现Runnable接口创建线程最常用,通过继承Thread类创建线程的话会占用继承位,因为java时单继承的,所以有时候会不太方便,通过实现Callable接口创建线程虽然有返回值,但是需要有返回值的时候很少,而且操作步骤比较多,也比较少用。

六种状态

新建状态(new)

//创建了,但没有被启动
Thread thread = new Thread();

可运行状态(runnable)

//启动之后,处于可运行状态,正在Java虚拟机中执行的状态
//可细分为:
//1.就绪状态:调用start方法以后等待jvm来调度的时候
//2.运行状态:jvm正在调度此线程。
thread.start();

阻塞状态(blocked)

受到阻塞,不能够继续运行,比如失去cpu的执行权限

等待状态(waiting)

无限期的等待另一个线程来执行的某一特定操作的线程处于这种状态,不能去争夺cpu的使用权限,只有等其他线程执行特定操作以后才可以有机会再次争夺cpu使用权,
比如wait()需要通过notify()或notifyAll()方法才可以唤醒
join()方法等,需要等待其他来(插队)加入的线程结束以后才可以继续运行。

定时等待状态(time_waiting)

//定时等待1秒
Thread.sleep(1000*1);
Thread.wait(1000*1);//如果想提前唤醒的话,需要通过notify()或notifyAll()方法唤醒
Thread.join(1000*1);
………………

终止状态(terminated)

运行完成或者被终止运行了,一旦进入终止状态,线程就会消亡,线程生命周期结束。

最后

感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

上一篇下一篇

猜你喜欢

热点阅读