Java实现线程的三种方式

Java实现线程的三种方式:

  1. 继承Thread

  2. 实现Runnable接口

  3. 实现Callable接口

1. 区别:

  1. 第一种方式继承Thread就不能继承其他类了,后面两种可以;

  2. 使用后两种方式可以多个线程共享一个target;

  3. Callable比Runnable多一个返回值,并且call()方法可以抛出异常;

  4. 访问线程名,第一种直接使用this.getName(),后两种使用Thread.currentThread().getName()。

下面我们通过代码来看一下实现和区别:

2. 三种实现:

//1. 继承Thread,重写run()方法
class Thread1 extends Thread {

    private int n = 5;

    @Override
    public void run() {
        while(n > 0) {
            System.out.println("name:" + this.getName() + ", n:" + n);
            n--;
        }
    }
}
//2. 实现Runnable接口,实现run()方法
class Thread2 implements Runnable {

    private int n = 5; 

    @Override
    public void run() {
        while(n > 0) {
            System.out.println("name:" + Thread.currentThread().getName() + ", n:" + n);
            n--;
        }
    }
}
//3. 实现Callable接口,实现call()方法,带有返回值和异常
class Thread3 implements Callable<String> {

    private int n = 5;

    @Override
    public String call() throws Exception {
        while(n > 0) {
            System.out.println("name:" + Thread.currentThread().getName() + ", n:" + n);
            n--;
        }
        return String.valueOf(n);
    }

}

如何使用:

从代码可以看出以上提到的区别1,3,4。那么区别2共享一个target是什么意思呢?

首先我们看一下上述代码的运行结果,

第一种:

第二种:

可以看到,这两种方式的结果一样,都是new了三个线程,每个线程内部循环5次。第二种方式并没有体现共用同一个target。如果我们将第二种创建线程的方式改为:

看一下运行结果:

可以看到,虽然也启动了3个线程,但是由于共享一个target,n的值改变了,其他两个线程也会知道,所以因此一共循环了5次。但是这里明明是7次啊,这是由于多线程的同步问题,可以给run方法加上synchronized关键字解决:

运行结果:

这里可能有点迷惑,只启动了一个线程啊。其实另外两个线程也启动了,只是这个时候n=0无法进入循环。我们可以加一行打印:

可以看到运行结果:

Last updated

Was this helpful?