Thread创建
package org.msi.threadLearn.demo01_create_thread;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic="c.Test1")
public class CreateThreadWay01 {
public static void createByThread(){
Thread t1 = new Thread(){
public void run(){
System.out.println(Thread.currentThread().getName()+":");
}
};
t1.setName("t1");
t1.start();
}
}
Runnable 结合 Thread创建
package org.msi.threadLearn.demo01_create_thread;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic="c.Test2")
public class CreateThreadWay02 {
public static void createByRunnable(){
Runnable r1 = new Runnable(){
public void run(){
System.out.println(Thread.currentThread().getName()+":running...thread02");
}
};
Thread t2 = new Thread(r1,"t2");
// 构造器已经初始化了线程名称,下面的set注入便可省略
// t2.setName("t2");
t2.start();
}
//lambda写法
public static void createByRunnable_lambda(){
Runnable r1 = () -> { System.out.println(Thread.currentThread().getName()+":running...thread02"); };
Thread t2 = new Thread(r1,"t2");
// 构造器已经初始化了线程名称,下面的set注入便可省略
// t2.setName("t2");
t2.start();
}
}
Callable 结合 FutureTask 结合 Thread创建
package org.msi.threadLearn.demo01_create_thread;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@Slf4j(topic = "c.Test3")
public class CreateThreadWay03 {
public static void createThreadByFutureTask(){
FutureTask<Integer> task3 = new FutureTask<>(new Callable() {
@Override
public Integer call() throws Exception {
System.out.println("running");
Thread.sleep(5000);
return 14;
}
}
);
Thread t3 = new Thread(task3,"t3");
t3.start();
// 等待task3的返回值,
try {
System.out.println(task3.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
请仔细看Callable方式的实现代码,下面是注意的几点:
- Callable:是一个泛型接口,里面也是只有一个抽象方法call(),特殊的是它有返回值(泛型指定的类型),且可以抛异常。
- call()返回值:到最后返回给了 FutureTask 对象 task,现在将task对象放入Thread类中创建一个新对象,thread.start() 正常启动,然后你可以通过 task.get() 来获取call()方法的返回值(task.get()的值就是新线程call()方法的返回值),
- 和Runnable的不同:Callable外面裹了一个FutureTask来封装成一个任务对象,既然是任务对象那就是说要接收到成果,任务就是新线程call()方法的执行,主线程 task对象有个get()在监控新线程call()的返回值,这个返回值就是任务的结果
(我的语言组织能力有限,流程执行只能写这么多了)