注册

JAVA创建线程的三种方式

JAVA创建线程的三种方式

一、JAVA创建线程的方式

JAVA中为了有异步计算,所以需要开启线程帮助后来计算,后台运行,在java中开启线程的方式有三种:

  1. 继承Thread类
  2. 实现Runnable接口
  3. 使用Callable和Future

二、线程创建方式的异同

  1. 继承Thread类: (1)通过Thread的构造方法创建线程 (2)通过start启动线程线程,且一个线程只能执行一次 (3)调用this.即可获得当前线程 (4)若要两个线程之间共享变量时,需要在声明为static变量,不推荐使用static变量,因为异步问题不容易控制。
  2. 实现Runnable接口 (1)线程只是实现了Runnable接口,还可以继承其他类和实现其他接口; (2)可以多个线程之间共享同一个目标对象(Runnable),非常适合多个线程处理同一份资源的情况;这一点比较难理解,看下面的代码示例会好理解。 (3)使用Thread.currentThread()可获得当前线程
  3. FutureTask:使用Callable和Future (1)Callable接口是Runnable接口的增强版 (2)Callable接口中的call()方法可以有返回值,也可以声明抛出异常

实现Runnable接口和继承Thread的方式区别: 继承Thread创建的线程是创建的Thread子类即可代表线程对象;而实现Runnable接口的创建的Runnable对象只能作为线程对象的target。 这也就是Runnable可以共享数据的原因。

FutureTask、Callable、Future之间的关系: 它实现了了RunnableFuture接口,而RunnableFuture接口又继承自Runnable和Future接口,所以FutureTask既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

public class FutureTask<V> implements RunnableFuture<V> {

}

三、实践

3.1 继承Thread类

class Test {

public static int number = 0;

public static void main(String[] args) {
TestThread testThread = new TestThread();
testThread.start();

TestThread2 testThread2 = new TestThread2();
testThread2.start();
}

public static class TestThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 10; i++) {
System.out.println(this.getName() + ":" + ++number);
}
}
}

public static class TestThread2 extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 10; i++) {
System.out.println(this.getName() + ":" + ++number);
}
}
}
}

3.2 实现Runnable接口

该代码示例中是两个线程共用一个Runnable,其中Runnable的数据是两个线程之间共享的。

class Test {
public static void main(String[] args) {
TestRunnable testRunnable = new TestRunnable();
// 共用一个Runnable,数据会按顺序输出
new Thread(testRunnable).start();
new Thread(testRunnable).start();

}

public static class TestRunnable implements Runnable {
int number = 0;

@Override
public void run() {
++number;
System.out.println(Thread.currentThread().getName() + " " + number);
}
}
}

3.3 FutureTask:使用Callable和Future

class Test {
public static void main(String[] args) {
FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>) () -> {
int i = 0;
while (i < 10) {
++i;
}
//call()方法的返回值
return i;
});

new Thread(task, "有返回值的线程").start();

try {
System.out.println("task.get():" + task.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}

0 个评论

要回复文章请先登录注册