此系列文章是参考《JAVA并发编程从入门到精通》一书写的一些读后笔记,其中也会进行扩展补充,写的不准确的地方还望广大同胞指出,大家一起学习,一起码奴。
线程简单实现的三种方式
- extends Thread
创建一个类继承Thread,并重写其run()方法,该方法即该线程所要做的事,即执行体
创建线程只需要实例化该类,也就是创建了线程对象
启动线程,只需要调用start()方法,即完成了线程的启动,示例代码如下:
//优势:编写简单,访问当前线程,无需使用Thread.currentThread()方法,直接使用this即可获得当前线程
//劣势:一个java类只能extend继承一个类,所以通常我们不会使用这样的方式
public class ThreadA extends Thread{
@Override
public void run() {
super.run();
try{
//TODO
Thread.sleep(1000L);
}catch (InterruptedException ex){
ex.printStackTrace();
}
System.out.println("这是线程A");
}
}
线程A执行方式如下:
public class ThreadMain {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
//启动线程A
threadA.start();
}
}
- implements Runnable:
创建一个类继承Runnable接口,和第一种方法相同要重写其run()方法
创建Runnable实现类的实例,并将这个实例作为Thread的target对象,创建出一个Thread对象,也就是说Thread才是真正的线程对象
启动线程则和第一种方法类似
//优势:只是实现了Runnable,还可以继承其他类;多个线程可以共享同一个target(下例子中的ThreadB )对象;
//劣势:如果要访问当前线程,则必须使用Thread.currentThread()方法;编程上较第一种方法稍微复杂一点
public class ThreadB implements Runnable {
@Override
public void run() {
try{
//TODO
Thread.sleep(1000L);
}catch (InterruptedException ex){
ex.printStackTrace();
}
System.out.println("这是线程B");
}
}
线程B执行方式如下:
public class ThreadMain {
public static void main(String[] args) {
ThreadB threadB = new ThreadB();
//与第一种启动方式有些不同,将ThreadB作为参数初始化Thread
new Thread(threadB).start();
}
}
- implements Callable
创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例
使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值
因为FutureTask实现了Runnable接口,所以可以使用FutureTask对象作为Thread对象的target创建并启动线程
调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
//这种方法与第二种的实现方式类似,与第二种方法差别最大的点在于,执行体即call(方法)可以有返回值,还可以通过FutureTask获取线程的执行结果,比第二种方式功能要更强一些
public class ThreadC implements Callable {
@Override
public Object call() throws Exception {
try{
//TODO
Thread.sleep(1000L);
}catch (InterruptedException ex){
ex.printStackTrace();
}
System.out.println("这是线程C");
return "thread C";
}
}
线程C执行方式如下:
public class ThreadMain {
public static void main(String[] args) {
ThreadC threadC = new ThreadC();
//通过FutureTask启动,后续有说明
FutureTask<String> futureTask = new FutureTask<String>(threadC);
new Thread(futureTask).start();
//获取返回值
try{
//get()方法会阻塞,直到子线程执行结束才返回
System.out.println("thread C 返回结果为:"+futureTask.get());
}catch (Exception ex){
ex.printStackTrace();
}
}
}