线程是操作系统最小的执行单位,也可以称为轻量级进程,一个进程可以有多个线程组成。一个线程一般有自己的计数器、堆栈、局部变量。我们都知道现在的计算机cup内核在不断的扩展,计算机速度越来越快,单一的线程已经满足不了人们的需求,用户线户与轻量线程N:M关联,而轻量线程与内核线程是一一对应的关系,因此一个线程最多可以使用一个内核,就算扩展再多内核对单线程也没太大影响。所以多线程被考虑到了,因为轻量级线程可以和用户线程混合使用。而用户线程正时我们编程使用的线程。
多线程下又会出现什么状况呢?如果资源只有一个的话,如何分配就是一个问题了。在我看来多线程就相当于战国时的诸侯,没有统一的中央集权,个诸侯国为争夺资源,不断的发动战争。这与jdk世界中,多线程争夺资源何其相像啊。如果不加以管理,在jdk的世界里只能崩盘。都说乱世出英雄,这个时候一个英才横空出世了,他就是java内存模型。为挽救多线程胡乱争夺资源产生的影响,他统一了jdk世界,首先规定各诸侯线程需要有自己的工作内存,获取主内存的资源时,线程不能直接拿主内存的资源,只能通过其他途径拷贝主内存的资源到工作内存中共自身使用。首先就让各线程定义了三大性。那就是原子性、可见性、有序性。它曰:遵守者,皆有资源。此时又有两个英才少年横空出世,他们就是synchronized与volatile。synchronized就比较好学又比较圆滑,三个性质都学会了,而volatile只会可见性与有序性。我们平常是不是都喜欢与圆滑的人打交道,所以我们经常使用synchronized。但是因为synchronized包含三个特性,他学的多,让他帮我们解决线程问题收费(消耗资源)肯定就更高了。所以对于我们这些没那么多资源的怎么办,然后我们发现,其实volatile也不错的,场景合适,就可以用他,又省资源,何乐而不为呢?所以呢其实我想说,用synchronized的人大都非富即贵,不用担心消耗资源,哈哈。
此时,人们不堪战乱疾苦,诸侯也心有所感,觉得资源应该更多倾注于本诸侯国的百姓身上,所以对争夺资源时,希望自身消耗更少一些,获取资源速度更快一些。java内存模型因此又颁布了一项规章制度,那就是heppen before原则,该原则定义了八项规则且只保证线程的有序性,此时举国欢呼,八项规则如下:
- 程序次序规则: 一个线程内,先写的代码优先发生于后写的代码
- 锁定规则:一个线程释放锁先行发生于另一个线程获得相同锁
- volatile变量规则:对一个volatile变量的写操作一定先行发生于后面对该变量的读操作
- 传递性规则:如果A先行发生于B,B先行发生于C,那么A先行发生于C
- 线程启动规则:thread对象的strart()方法先行发生于此线程的每个动作
- 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程检测到中断事件的发生
- 线程终止规则:线程的所有操作先行发生于线程的终止检测
- 对象终结规则:一个对象初始化完成先行于它发生finalize()方法
Java内存模型既然已经制定好各项规章制度,那么接下来就看各诸侯线程该如何去执行了。线程调度资源有两种方式,协同式线程调度与抢占式线程调度。
协同式线程调度是指,一个线程调度资源时,执行完后再到下过一个线程调度,但是这样会导致一个问题,就是如果一个线程阻塞了,那么后面的线程就没法干活了。
抢占式线程调度是指,每个线程都由系统分配一定的时间,如果超时了,不好意思,你先让让,让后面的线程来拿资源。
有没有发现,现在越来越多的东西都是不相互依赖了,而是请第三方参与管理,这就是控制反转了。
最简单的线程、多线程的解析
最新推荐文章于 2022-12-14 08:15:10 发布