【Java】创建线程有2种方式?|Java 刷题打卡

155 阅读2分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看活动链接

创建线程两种方式:

  1. 继承自Thread

继承Thread,重写方法run()

public class MyThread extends Thread{

	public void run() {}
}
  1. 实现Runnable接口

推荐使用 实现run方法,符合里氏代换原则

public class MyThread implements Runnable {

	public void run() {}
}

start()run() 区别:

  1. start() 方法来启动线程,真正实现了多线程运行。

    这时无需等待 run 方法体代码执行完毕,可以直接继续执行下面的代码;通过调用 Thread 类的start() 方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此 Thread 类调用方法 run() 来完成其运行操作的, 这里方法 run() 称为线程体,它包含了要执行的这个线程的内容, Run 方法运行结束, 此线程终止。然后 CPU 再调度其它线程。

  2. run() 方法当作普通方法的方式调用。

    程序还是要顺序执行,要等待 run 方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。

应用如下:

public class Test {
    public static void main(String[] args) {

        Thread thread1 = new Thread(new Runner1());
        Thread thread2 = new Thread(new Runner2());
        // thread1.start();
        // thread2.start();
        thread1.run();
        thread2.run();
    }
}

// 实现了Runnable接口,jdk就知道这个类是一个线程
class Runner1 implements Runnable { 
    public void run() {
        for (int i = 0; i < 2; i++) {
            System.out.println("进入Runner1运行状态——————————" + i);
        }
    }
}

// 实现了Runnable接口,jdk就知道这个类是一个线程
class Runner2 implements Runnable { 
    public void run() {
        for (int i = 0; i < 2; i++) {
            System.out.println("进入Runner2运行状态==========" + i);
        }
    }
}

Tips:

  1. 其实 CallableFuture 本身并不能产生新的线程,它们需要借助其他的比如 Thread 类或者线程池才能执行任务。
  2. Thread 里源码注释也只写了两种方式。
  1. 实现Callable接口

前面两种,在任务执行完成后,无法直接获取执行结果,需要借助共享变量等来获取。 CallableFuture则很好地解决了这个问题

异常: call() 可以抛出异常。 Runnable只有通过setDefaultUncaughtExceptionHandler()的方式才能在主线程中捕捉到子线程异常

public class MyThread implements Callable<Integer> {

	@Override
	public Integer call() throws Exception {
		
		return 1;
	}
}