多线程
个人笔记⑥
多线程概述
线程和进程都是一种抽象的概念,线程是一种比进程还小的抽象,线程和进程都可用于实现并发。 一个进程里只有一个线程,进程本身就是线程。 所以线程有时被称为轻量级进程 (也可以是一个)线程。
进程
一般由程序,数据集合和进程控制块三部分组成。
进程一般指的是正在执行的程序,其实就是应用程序在内存中运行的那片空间。
线程
进程中的执行单元。负责进程中的程序执行,一个进程中,至少有一个线程。
进程与线程的区别
- 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
- 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
- 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他进程不可见;
- 调度和切换:线程上下文切换比进程上下文切换要快得多
多线程
Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径。
多线程是多任务的一种特别的形式。多线程比多任务需要更小的开销。
多线程能满足程序员编写非常有效率的程序来达到充分利用 CPU 的目的,因为 CPU 的空闲时间能够保持在最低限度。
继承Thread类创建多线程
创建一个线程的一种方法是创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。
继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。
调用run方法和start方法的区别
调用run方法不开启线程,仅仅是对象调用方法
start方法,开启新线程并让线程执行,同时能调用run方法。可以避免在主函数中,只有一个主线程来负责两个线程对象。
关于Tread类的重要方法
该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
题目
1、Thread类位于下列哪个包中?
A、java.io
B、java.lang
C、java.util
D、java.awt
实现Runnable接口创建多线程
创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。
为了实现 Runnable,一个类只需要执行一个方法调用 run()
两种实现多线程方式的对比
- 采用实现 Runnable、 接口的方式创建多线程时,线程类只是实现了 Runnable 接口,还可以继承其他类。
- 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
使用Runnable接口避免了单继承的局限性,更常用。
线程休眠
Thread类包含一个静态sleep()方法,它使线程在指定的持续时间内休眠。
Thread.sleep()方法接受超时作为参数。
使用 sleep 方法可以让让当前线程休眠,时间一到当前线程继续往下执行,在任何地方都能使用,但需要捕获 InterruptedException 异常。
关于sleep与wait
sleep 一般用于当前线程休眠,或者轮循暂停操作,wait 则多用于多线程之间的通信。 sleep 是 Thread 类的静态本地方法,wait 则是 Object 类的本地方法。
最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
后台线程
后台线程也称为守护线程 (比如JVM处理垃圾回收 使用的就是后台线程), 我们创建的线程一般用于处理我们自己的某些任务,而后台线程主要用于一些公共的任务以提供服务。
我们创建的线程可以在start()启动前使用 thread.setDaemon(true); 来将其设置为后台线程,使用isDaemon()来判断线程是否为后台线程。