线程的创建以及Thread与Runnable的关系(个人理解)

线程和进程

线程

  • 一个进程之内可以分为一到多个线程
  • 一个线程就是一个指令流,将指令流中的一条条指令交给cpu去执行,
  • Java中,线程作为最小的调度单位,进程作为最小的资源分配的单位,在windows 中进程只是作为线程的容器
  • 首先一个线程作为进程的子集,一个进程可以分为一个或者多个线程,而线程本身是指令流,将指令交给cpu 去执行,对于Java来讲,线程是最小的 调度单位 ,进程是最小的 资源调度单位

进程和线程的对比

  • 进程基本上相互独立,而线程作为进程的一个子集
  • 进程拥有共享的资源,比如:存储空间等,供其内部线程共享
  • 通信
    • 同一台计算机的进程通信是IPC(inter process commucation)
    • 不同之间计算机的通信要遵循协议,如 HTTP
  • 线程的通信相对简单,因为他们共享进程中的内存,如:共享变量
  • 线程更加轻量,上上下文的切换会比进程要低

Java线程

创建

1. 直接使用 Thread

// 构造方法的参数是给线程指定名字,推荐
Thread t1 = new Thread("t1") {
 @Override
 // run 方法内实现了要执行的任务
 public void run() {
 log.debug("hello");
 }
};
// 启动线程
t1.start();

2.使用Runnable 配合 Thread

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

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

// 在Java 8 以后 可以使用lamda 表达式
// 创建任务对象
Runnable task2 = () -> log.debug("hello");
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();

3.FutureTask 配合 Thread

Future 能够接受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

Thread 和 Runnable 的关系

  • Thread 实现了 Runnable 接口,Runnable 依赖Thread 类的start方法,在start 方法中会调用start0方法,接着就会通过jvm 进行资源调度,系统分配,回调run 方法执行线程的具体操作,(在我的理解中,新的线程就是在这个时候产生的),就类似于 Thread 想一个线程的载体,而Runnable则负责线程的具体工作。

你可能感兴趣的:(多线程,后端,多线程)