java 线程创建和运行

直接使用 Thread类
// 创建线程对象
Thread t = new Thread() {
 public void run() {
 // 要执行的任务
 }
};
// 启动线程
t.start();

使用 Runnable 配合 Thread

把【线程】和【任务】(要执行的代码)分开

  • Thread 代表线程
  • Runnable 可运行的任务(线程要执行的代码)

例如:
// 创建线程对象

Runnable runnable = new Runnable() {
	public void run(){
 		// 要执行的任务
		}
};
// 创建线程对象
Thread t = new Thread( runnable );
// 启动线程
t.start(); 

Java 8 以后可以使用 lambda 精简代码

// 创建任务对象
Runnable task2 = () -> log.debug("hello");
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();

原理之 Thread 与 Runnable 的关系

分析 Thread 的源码,理清它与 Runnable 的关系

    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
                      
                      ...
                      this.target = target;
        			...
}
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

直接使用 Thread类 重写了run 方法

使用Runnable配合的走Thread的run 方法,但因为target 不为空,执行Runnable的run方法

小结

  • 方法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);

输出

19:22:27 [t3] c.ThreadStarter - hello
19:22:27 [main] c.ThreadStarter - 结果是:100

观察多个线程同时运行发现:

  • 进程交替执行

  • 谁先谁后,不由我们控制


版权声明:本文为olivia12344321原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。