线程

线程和进程

进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位,每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。

线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。一个线程是一个程序内部的顺序控制流。

多进程:同时运行多个任务(程序)。
多线程:在同一应用程序中有多个顺序流同时执行。

线程的概念模型

●虚拟的CPU,封装在 java. lang. Thread类中。

●CPU所执行的代码,传递给 Thread类。

●CPU所处理的数据,传递给 Thread类。

●Java的线程是通过 java. lang. Thread类来实现的。、

●每个线程都是通过某个特定 Thread对象的方法run()来完成其操作的方法run()称为线程体。

构造线程的三种方法

定义一个线程类,它继承类 Thread并重写其中的方法run();
提供一个实现接口 Runnable的类作为线程的目标对象,在初始化;
通过Callable和Future创建线程。

一个 Thread类或者 Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体run()。

main线程已经执行完后,新线程才执行完,main方法调用 thread. start()方法启动新线程后并不等待其run方法返回就继续运行,线程的run方法在一边独自运行,不影响原来的main方法的运行。

Runnable接口

只有一个run()方法,Thread类实现了 Runnable接囗,便于多个线程共享资源.

□Java不支持多继承,如果已经继承了某个基类,便需要

现 Runnable接口来生成多线程

口以实现 Runnable的对象为参数建立新的线程

口sta方法启动线程就会运行run(方法

多线程的同步控制

●有时线程之间彼此不独立、需要同步

口线程间的互斥

同时运行的几个线程需要共享一个(些)数据

共享的数据,在某一时刻只允许一个线程对其进行操作

“生产者/消费者”问题

假设有一个线程负责往数据区写数据,另一个线程从同一数据

区中读数据,两个线程可以并行执行

如果数据区已满,生产者要等消费者取走一些数据后才能再写

当数据区空时,消费者要等生产者写入一些数据后再取

●线程同步

口互斥:许多线程在同一个共享数据上操作而互不干扰,同一时刻

只能有一个线程访问该共享数据。因此有些方法或程序段在同

时刻只能被一个线程执行,称之为监视区

口协作:多个线程可以有条件地同时操作共享数据。执行监视区代

码的线程在条件满足的情况下可以允许其它线程进入监视区

synchronized-一线程同步关键字,实现互斥

口用于指定需要同步的代码段或方法,也就是监视区

口可实现与一个锁的交互。例如

synchronized(对象)(代码段

口 synchronized的功能是:首先判断对象的锁是否在,如果在就获得锁

然后就可以执行紧随其后的代码段;如果对象的锁不在(已被其他

线程拿走),就进入等待状态,直到获得锁

口当被 synchronized限定的代码段执行完,就释放锁

●后台线程

口也叫守护线程,通常是为了辅助其它线程而运行的线程

口它不妨碍程序终止

口一个进程中只要还有一个前台线程在运行,这个进程就不会结束;如

果一个进程中的所有前台线程都已经结束,那么无论是否还有未结束

的后台线程,这个进程都会结束

口“垃圾回收”便是一个后台线程

口如果对某个线程对象在启动(调用stat方法)之前调用了

setDaemon(true方法,这个线程就变成了后台线程

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

诞生状态

口线程刚刚被创建

就绪状态

口线程的 start方法已被执行

口线程已准备好运行

运行状态

口处理机分配给了线程,线程正在运行

阻塞状态( Blocked)

口在线程发出输入/输出请求且必须等待其返回

口遇到用 synchronized标记的方法而未获得锁

口为等候一个条件变量,线程调用wat(方法

●休眠状态( Sleeping)

口执行seep方法而进入休眠

死亡状态

口线程已完成或退出

线程调度

口在单CPU的系统中,多个线程需要共享CPU,在任何时间点

上实际只能有一个线程在运行

口控制多个线程在同一个CPU上以某种顺序运行称为线程调度

Java虚拟机支持一种非常简单的、确定的调度算法,叫做固

定优先级算法。这个算法基于线程的优先级对其进行调度

考虑这些线程在运行时环境下的调度和交替执行,也

不需要进行额外的同步,或者在调用方进行任何其他

的协调操作,调用这个对象的行为都可以获得正确的

结果,那这个对象是线程安全的。

Java线程安全 互斥同步、非阻塞同步、无同步方案

互斥同步

●同步的互斥实现方式:临界区( Critical Section),互斥量

( Mutex),信号量( Semaphore)

● Synchronized关键字:经过编译后,会在同步块前后形成

monitorenter和 monitorexit两个字节码。

口(1) synchronized同步块对自己是可重入的,不会将自己锁死;

口(2)同步块在已进入的线程执行完之前,会阻塞后面其他线程的进入

采用 synchronized,重入锁可实现:等待可中断、公平锁、锁

可以绑定多个条件

Synchronized表现为原生语法层面的互斥锁,而 RenentrantLock表

现为API层面的互斥锁

●阻塞同步:互斥同步存在的问题是进行线程阻塞和唤醒所带来的性

能问题,这种同步称为阻塞同步( Blocking Synchronization)。这是

种悲观并发策略

●非阻塞同步:不同于悲观并发策略,而是使用基于冲突检测的乐观

并发策略,就是先进行操作,如果没有其他线程征用共享数据,则

操作成功;否则就是产生了冲突,采取不断重试直到成功为止的策

种策略不需要把线程挂起,称为非阻塞同步

●使用硬件处理器指令进行不断重试策略(DK15以后

口测试并设置( Test-and-set)

口获取并增加( Fetch- and-Increment)

口交换(Swap)

口比较并交换( Compare-and-Swap,简称CAS)

口加载链接,条件存储( Load-Linked, Store-conditional简称LLSC)

例:java实现类 AtomicInteger, AtomicDouble等等。

●可重入代码:也叫纯代码。相对线程安全来说,可以保证线程安全。

可以在代码执行过程中断它,转而去执行另一段代码,而在控制权

返回后,原来的程序不会出现任何错误。

●线程本地存储:如果一段代码中所需要的数据必须与其他代码共享,

那就看看这些共享数据的代码是否能保证在同一个线程中执行,如

果能保证,就可以把共享数据的可见范围限定在同一个线程之内,

这样无需同步也能保证线程之间不出现数据争用问题。

锁优化(源自」DK6)

●自旋锁

●自适应锁

●锁消除

●锁粗化

偏向锁

●互斥同步存在的问题:挂起线程和恢复线程都需要转入内核态中完

成,这些操作给系统的并发性能带来很大的压力

●自旋锁:如果物理机器有一个以上的处理器能让两个或以上的线程

同时并行执行,那就可以让后面请求锁的那个线程“稍等一会”,

但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放

锁。为了让线程等待,我们只需要让线程执行一个忙循环(自旋)

这项技术就是自旋锁。Java中自旋次数默认10次

自适应自旋

●自适应意味着锁自旋的时间不再固定,而是由前一次在同一个锁

上的自旋时间及锁拥有者的状态来决定。如果在同一个锁对象上,

自旋等待刚刚成功获得锁,并且持有锁的线程正在运行中,那么

虚拟机就会认为这次自旋也很有可能再次成功,进而它允许自旋

等待相对更长的一段时间。

锁消除

●定义:JVM即时编译器在运行时,对一些代码上要求同步,但是

被检测到不可能存在共享数据竞争的锁进行消除

●判定依据:如果判断在一段代码中,堆上的所有数据都不会逃逸

出去从而被其他线程访问到,那就可以把它们当作栈上数据对待,

认为他们是线程私有的,同步加锁自然无需进行。

锁粗化

通常我们的代码总是将同步块的作用范围限制得尽量小,只在共享数

据的实际作用域中才进行同步,这样是为了使得同步操作的数量尽可

能变小

●另一种情况是,如果一系列的连续操作都对同一个对象反复加锁,甚至加

锁操作是出现在循环体中,那即使没有线程争用,频繁的进行互斥同步也

会导致不必要的性能损耗,此时只需要将同步块范围扩大即可。即:锁粗

偏向锁

●目的:消除数据无竟争情况下的同步原语,进一步提高程序运行的性

能。偏向锁就是在无竟争的情况下把整个同步都消除掉,连CAS操作

都不做

●偏向:意思是这个锁会偏向于第一个获得它的线程,如果在接下来的

执行中,该锁没有被其他线程获取,则持有偏向所得线程永远不需要

再进行同步

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 229,406评论 6 538
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,034评论 3 423
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 177,413评论 0 382
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,449评论 1 316
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,165评论 6 410
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,559评论 1 325
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,606评论 3 444
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,781评论 0 289
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,327评论 1 335
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,084评论 3 356
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,278评论 1 371
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,849评论 5 362
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,495评论 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,927评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,172评论 1 291
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,010评论 3 396
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,241评论 2 375

推荐阅读更多精彩内容

  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,978评论 1 18
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,477评论 1 15
  • 线程池ThreadPoolExecutor corepoolsize:核心池的大小,默认情况下,在创建了线程池之后...
    irckwk1阅读 738评论 0 0
  • 引用自多线程编程指南应用程序里面多个线程的存在引发了多个执行线程安全访问资源的潜在问题。两个线程同时修改同一资源有...
    Mitchell阅读 2,016评论 1 7
  • 在之前的课程中,我们已经学习了进程相关的知识。进程是计算机程序被执行的一个实例(instance),一个进程可能由...
    夏威夷的芒果阅读 923评论 0 2