javaWeb学习乱七八糟风暴Android知识

【有梦想的IT人】多线程的创建,使用,管理

2017-06-27  本文已影响256人  夏尼采

最近看到很多关于线程,进程,管理和使用的问题,所以觉得有必要总(zhuang)结(bi)一下!

共同学习

1.线程,进程,以及并发和并行

什么是进程?
① 进程是系统进行资源分配的最小单位,也是系统进行资源调度的基本执行单元。
② 它是程序的一次执行过程。简单点的说“进程是正在运行的程序的实例”。
③ 每个进程运行在受保护的独立的内存空间内,进程和进程之间互不干扰。

什么是线程?

① 线程是CPU调度的最小单位,是进程中的一个实体在(也是进程调度的单位)。
② 每一个应用程序在启动之后,都会默认开启一条主线程,除了主线程,其他的线程都是子线程。
③ 一个线程可以创建和撤销另一个线程。
④同一个进程当中的线程共享该进程的资源

进程、线程区别是什么?

① 进程和线程都是程序运行的基本单元,一个程序至少有一个进程,一个进程至少有一个线程。
② 线程的划分尺度小于进程,使得多线程程序的并发性高。
③ 同一个进程中的多个线程之间可以并发执行,线程共享内存,从而极大地提高了程序的运行效率。

并发
简单的来说就是指一个时间段内,多个任务同时处于运行活跃状态,而不是在同一时刻运行多个任务。那问题来了,为什么我们感觉像是多个任务同时执行的呢?这是因为每个线程都被分了一个时间段,叫做时间片。因为CPU处理速度很快,所以看上去就是多个任务在同时执行,实际上就只有一个任务在执行。

并行
并行相对来说能简单些,指若干个程序段同时在系统中运行,这些程序的执行在时间上是重叠的,一个程序段的执行尚未结束,另一个程序段的执行已经开始,无论从微观还是宏观,程序都是一起执行的。

Paste_Image.png

你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以我认为它们最关键的点就是:是否是『同时』。

2.创建线程的两种方法

①继承Thread类
该子类必须重写 Thread 类的 run 方法,接下来new这个对象的实例。然后调用start()方法创建并启动线程。需要注意的是:程序是在调用start()方法之后,才开辟了一个子线程,并执行run方法。如果你直接调run方法(比如在main方法最下面写上m1.run();),它就是在主线程中执行的,而且是要比开辟三个线程要快的,这就说明新线程创建的过程不会阻塞主线程的后续执行。
注意:同一个Thread不能重复调用start方法,会出现java.lang.IllegalThreadStateException异常。
②实现Runnable接口
重写run()方法,然后调用new Thread(runnable)的方式创建一个线程,然后调用start()方法启动线程。
注意:Runnable接口只能通过Thread的静态方法Thread.currentThread()取得当前的Thread对象,再调用getName()方法,来取得当前线程的名字。
实现Runnable接口比继承Thread类所具有的优势:

3.线程的生命周期

Paste_Image.png

4.线程管理

1.线程调度
对于计算机的CPU(以单核为例),在任意时刻只能执行一条指令,每个线程只有获得CPU的使用权才能执行指令。当有多个处于可运行状态的线程在等待CPU,JVM的一项任务就是负责线程的调度。JVM按照特定机制为多个线程分配CPU的使用权过程就是线程调度。
线程调度的两种模型:分时调度模型和抢占式调度模型。
① 分时调度模型:是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片,这个比较好理解。
② JVM采用抢占式调度模型:就是让线程抢夺CPU资源,运行顺序是不确定的,优先权高的线程,会有一定几率优先占用CPU。处于运行状态的线程会一直运行下去,直至它不得不放弃CPU。比如线程运行完毕、线程阻塞、运行被打断。

2.线程管理之设置线程优先级
Java线程优先级共有10个级别,优先级较高的线程会获得较多的运行机会,取值范围是从1到10。如果小于1或大于10,则JDK抛出异常IllegalArgumentException()。Thread类有以下三个静态常量:
① static final int MAX_PRIORITY :值为10,代表最高优先级。
② static final int MIN_PRIORITY :值为1,代表最低优先级。
③ static final int NORM_PRIORITY:值为5,代表默认优先级。

注意:
① 并不是说优先级较高的线程一定会在优先级较低的线程之前运行,优先级高这里是指获得较多的运行机会。
② 优先级高的线程会大部分先执行完,并不一定会全部执行完毕。
③ 子线程的优先级是跟父类优先级是一样的。

设置和获取优先级方法:
thread.setPriority(Thread.MIN_PRIORITY)和 thread.getPriority()

5.线程管理之守护线程

我们在程序中创建的线程默认都是用户线程(User Thread)。与用户线程对应则是守护线程(Daemon Thread),也可称之为后台线程,它的作用就是为其它线程提供服务的。守护线程使用的情况较少,举例来说:JVM的垃圾(GC)回收线程就是守护线程。

注意:
① 当所有的用户线程都结束退出的时候,守护线程也就没啥可服务的了,随着线程的结束而结束。如果JVM只剩下守护线程,虚拟机就会退出。
② 守护线程会随时中断,因此不要在如输入输出流,数据库连接等场合使用守护线程。
③ 守护线程并非是JVM内部可提供,我们自己可以根据需要来设定守护线程。可以通过isDaemon和setDaemon方法来判断和设置一个线程为守护线程。
④ 守护线程必须在start方法前设置,否则会抛出IllegalThreadStateException异常。
⑤ 一个守护线程创建的子线程依然是守护线程。

6.线程管理之常用方法

1.简单方法
public static int activeCount():返回当前线程的线程组中活动线程的数目。
public static Thread currentThread():返回对当前正在执行的线程对象的引用。
public long getId():返回该线程的标识符,线程 ID 是唯一的。
public final void setName(String name):改变线程名称。
public final String getName():返回该线程的名称。
public String toString():返回该线程的字符串表示形式,包括线程名称、优先级和线程组。
public void start():使该线程开始执行,Java 虚拟机调用该线程的 run 方法。

2.比较重要的方法:

3.wait()与sleep()方法的区别
相同点: 二者都可以让线程处于冻结状态。

不同点:首先应该明确sleep方法是Thread类中定义的方法,而wait方法是Object类中定义的方法。

①sleep方法必须人为地为其指定时间。wait方法既可以指定时间,也可以不指定时间。
②sleep方法时间到,线程处于临时阻塞状态或者运行状态。wait方法如果没有被设置时间,就必须要通过
notify或者notifyAll来唤醒。
③sleep方法不一定非要定义在同步中。wait方法必须定义在同步中。
④当二者都定义在同步中时,线程执行到sleep,不会释放锁。线程执行到wait,会释放锁。

7.synchronized关键字

Our youth never dies,just fades away.

嗨~我是夏尼采,一个有梦想的IT男

每周输出3篇有用的文章,目标是签约简书。

如果文章对您有帮助,希望能点个赞或者关注我。

您的关注和点赞是对我最大的鼓励,感谢您的阅读

上一篇 下一篇

猜你喜欢

热点阅读