我们熟悉的继承extends和实现runnable接口实现线程,但是这就算两种吗?首先,先写出来这最基础的两种。
Runnable接口实现线程方法
public class ThreadBaseDemo1 implements Runnable {
public static void main(String[] args) {
new Thread(new ThreadBaseDemo1()).start();
}
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行");
}
}
Thread类继承线程方法
public class ThreadBaseDemo1 extends Thread {
public static void main(String[] args) {
new Thread(new ThreadBaseDemo1()).start();
}
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
继续拓宽
其实还是有很多不同的形式实现线程的方法,下面看一下callable实现线程的方法
Callable接口实现线程方法
public class ThreadBaseDemo1 implements Callable<Integer> {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(16);
Future<Integer> future = executorService.submit(new ThreadBaseDemo1());
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
return sum;
}
}
在这有的人会问,前两者和callable有什么区别呢?
callable的实现可以拥有返回值,并且支持抛出异常,这样就可以实现异步的思想,而runnable的返回值为void且不能抛出异常
future就是用来接收线程池处理的结果的。
但是扯了这么多,线程到底有多少种方式?
一种
请看下Thread的实现,里面主要的就是start方法,start底下的run方法就是执行传入target,中的run,所以不管是继承thread,或者是实现Runnable接口,还是用线程池submit,再或者是用future接收它,都是执行这个target.run()。所以只有一种方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
哪种实现更好?
Java只能继承一个类,但是可以实现N个接口,从耦合度或者是组合聚合的角度上来看,当然是实现Runnable接口更好,毕竟物依稀为贵嘛。
如何正确的中断线程?
public class ThreadBaseDemo1 implements Runnable {
public static void main(String[] args) {
Thread thread = new Thread(new ThreadBaseDemo1());
thread.start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
@Override
public void run() {
int sum = 0;
for (int i = 0; i < 100 && !Thread.currentThread().isInterrupted(); i++) {
sum += i;
}
System.out.println(sum);
}
}
每次执行累加业务之前,我们都先看看这个线程是否已经被终止,也就是说isInterrupted。
睡眠的时候会感知到中断吗?
public class ThreadBaseDemo1 implements Runnable {
public static void main(String[] args) {
Thread thread = new Thread(new ThreadBaseDemo1());
thread.start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
@Override
public void run() {
int sum = 0;
for (int i = 0; i < 100 && !Thread.currentThread().isInterrupted(); i++) {
sum += i;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(sum);
}
}
在睡眠时期,可以被感知中断的,但是不能终止线程继续工作。