以下主要内容参考自csdn学院课程"Java并发编程精讲",讲师"祝侦科"。
线程的创建
方式一: 实现Runnable 接口 重写run方法
代码: public static void main(String[] args) {
A a =new A();
Thread b=new Thread(a);
b.start();
}
static class A implements Runnable{
@Override
public void run() {
System.out.println("创建线程方式一,线程已创建。");
}
}
方式二:继承Thread类重写run方法
代码: public class createThreadWay2 {
public static void main(String[] args) {
Thread a =new MyThread();
a.start();
}
static class MyThread extends Thread {
@Override
public void run() {
System.out.println("创建线程方式二,线程已创建。");
}
}
}
方式三 :仿造方式一用到不同的类声明类实现Callable接口,重写其call方法,可带有返回值。新建FutureTask对象加载创建的Callable对象,再使用Thread去加载FutureTask对象并调用Star方法。使用FutureTask的get()方法即可获取线程的返回结果。
代码:
public class createThreadWay3 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable myCallable =new MyCallable();
FutureTask futureTask=new FutureTask(myCallable);
new Thread(futureTask).start();
Object a=futureTask.get();
System.out.println("线程返回--->>"+a.toString());
}
static class MyCallable implements Callable{
@Override
public Object call() throws Exception {
System.out.println("创建线程方式三,线程已创建。");
return "方式三线程的返回";
}
}
}
与本课程无关笔记:内部类的使用须使用static修饰,不然不可创建对象,内部类创建对象时需先创建内部类
所在的类。
方式四:通过线程池,重写Callable的call方法或者runable的run方法,使用ExecutorService对象调用excute/submit方法加载以上对象,使用submit提交的可使用Future来获取线程执行结果。
代码:
public class createThreadWay4 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService=Executors.newFixedThreadPool(2);
Callable myCallable =new MyCallable();
Runnable myRunnable =new MyRunnable();
//1
executorService.execute(myRunnable);
//2
Future a = executorService.submit(myCallable);
System.out.println("submit2返回的输出---》》"+a.get().toString());
//3
Future b = executorService.submit(myRunnable);
System.out.println("submit3返回的输出---》》"+b.get());
}
static class MyCallable implements Callable{
@Override
public Object call() throws Exception {
System.out.println("MyCallable的线程");
return "MyCallable线程的返回 ";
}
}
static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("MyRunnable的线程");
}
}
}
运行结果:
源码解剖。
线程Thread的star()方法的本质是调用Runable对象的run方法。
线程的Callable是如何获取返回结果的:
主要是由于FutureTask类,该类是最终重写的是Runable对象的run方法,在run方法中会去调用Callable对象的call方法并将返回值塞入outcome(线程的返回结果可通过get获取)中。