3.1 创建和运行线程
方法一,直接使用 Thread
// 创建线程对象
Thread t = new Thread() {
public void run() {
// 要执行的任务
}
};
// 启动线程
t.start();
// 构造方法的参数是给线程指定名字,推荐
Thread t1 = new Thread("t1") {
@Override
// run 方法内实现了要执行的任务
public void run() {
logger.info("我是一个线程");
}
};
t1.start();
2020-11-15 15:04:11.157 [t1] INFO cn.zhou.shu.ssm.helloworld-我是一个线程
方法二,使用 Runnable 配合 Thread
把【线程】和【任务】(要执行的代码)分开
Thread 代表线程
Runnable 可运行的任务(线程要执行的代码)
Runnable runnable = new Runnable() {
public void run(){
// 要执行的任务
}
};
// 创建线程对象
Thread t = new Thread( runnable );
// 启动线程
t.start();
例如:
// 创建任务对象
Runnable task2 = new Runnable() {
@Override
public void run() {
logger.info("我是一个线程");
}
};
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();
2020-11-15 21:33:27.913 [t2] INFO cn.zhou.shu.ssm.helloworld-我是一个线程
Java 8 以后可以使用 lambda 精简代码:
// 创建任务对象
Runnable task2 = () -> logger.info("我是一个线程");
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();
小结:
方法1 是把线程和任务合并在了一起,方法2 是把线程和任务分开了
用 Runnable 更容易与线程池等高级 API 配合
用 Runnable 让任务类脱离了 Thread 继承体系,更灵活
方法三,FutureTask 配合 Thread
FutureTask 能够接收 Callable 类型的参数,用来处理有返回结果的情况
// 创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {
log.debug("hello");
return 100;
});
// 参数1 是任务对象; 参数2 是线程名字,推荐
new Thread(task3, "t3").start();
// 主线程阻塞,同步等待 task 执行完毕的结果
Integer result = task3.get();
log.debug("结果是:{}", result);
package cn.zhou.shu.ssm;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class helloworld {
private static Logger logger = LoggerFactory.getLogger(helloworld.class);
public static void main(String[] args) throws InterruptedException, ExecutionException {
/*Thread t = new Thread() {
@Override
public void run() {
logger.info("我是一个线程");
}
};
t.setName("t1");
t.start();*/
/*Runnable task = new Runnable() {
public void run() {
logger.info("我是一个线程");
}
};
Thread t = new Thread(task, "t2");
t.start();*/
FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
logger.info("我是一个线程");
Thread.sleep(2000);
return 100;
}
});
Thread t1 = new Thread(task,"t1");
t1.start();
Integer result = task.get();
logger.info("结果是:{}", result);
}
}
2020-11-15 22:14:31.068 [t1] INFO cn.zhou.shu.ssm.helloworld-我是一个线程
2020-11-15 22:14:33.073 [main] INFO cn.zhou.shu.ssm.helloworld-结果是:100
参考:
在JDK1.5之前,创建线程就只有两种方式,即继承java.lang.Thread类和实现java.lang.Runnable接口;而在JDK1.5以后,
增加了两个创建线程的方式,即实现java.util.concurrent.Callable接口和线程池。下面是这4种方式创建线程的代码实现。