Java基础之Java线程

1. 线程的使用

继承Thread类或者实现Runnable接口

Thread 和Runnable的区别

  • 克服java单继承的缺点
  • 当多个线程共用同一资源时,用Runnable比较好
    因为在创建线程的时候,构造方法中有一个Runnable的参数,多个线程可以共用这一个Runnable

2. 线程中用到的一些关键字和方法

synchronized
互斥,使得共享的资源同一时刻只能由一个线程占用

volatile
保证了线程写入的值能够及时刷新到主内存
线程读取的值总是从主内存中读取的

一些常用方法
start
启动一个线程

join
加入一个线程,加入的线程先执行完毕,在执行其他的线程

stop
错误的终止线程的方法,它会使得线程戛然而止,没办法做一些线程结束的后续操作

interrupt
当线程处于非阻塞状态时,则将中断标志修改为true,在此基础上如果调动sleep,wait,join等阻塞方法时,将会抛出InterruptedException异常,并且将中断标志修改为false。因此最正确的终止线程的方法,应该是通过标志位来判断。

sleep
线程进行睡眠

wait
线程等待,可以设置等待的时间,如果没有设置时间,就需要进行唤醒操作

notify
随机唤醒一条处于等待状态的线程

notifyAll
唤醒所有处于等待状态的线程

yield
让出处理器的时间,使得其他线程可以竞争资源

3. 线程的生命周期

创建 new Thread

就绪 start notify notifyAll

运行 执行run方法

阻塞 sleep wait block(被synchronized锁阻塞)

终止 run方法执行完毕

4. java线程非分类

用户线程
运行在前台,执行具体任务

守护线程
运行在后台,为其他前台线程服务
Thread.setDaemon(true) 可以将线程设置为守护线程
注意,要在start之前调用,在守护线程中创建的线程也是守护线程
用户线程执行完毕后,守护线程自动终止

工具
jstack 查看线程快照
cmd 命令 jstack -l pid 查看进程中 线程的信息

5. java多线程的可见性问题

可见性
一个线程对共享变量值的修改,能够及时地被其他线程所看到

共享变量
一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量

JMM(java内存模型)
描述了java程序中各种变量(线程共享变量)的访问规则,以及在jvm中将变量存储到内存和从内存中读取出变量的底层细节
1.所有变量都存储在主内存中
2.每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的一份拷贝)

实现共享变量的可见性必须保证以下两点
1.线程修改的共享变量能够及时从工作内存中刷新到主内存中
2.其他线程能够及时将共享变量的值从主内存中刷新到自己的工作内存中去

实现方式
synchronized
线程解锁前,将共享变量的值及时地更新到主内存中去
线程加锁后,将清空工作内存中共享变量的值,并从主内存中读取共享变量的值
(加锁与解锁要是同一把锁)
volatile

重排序
代码书写的顺序与代码实际执行的顺序不同,指令冲排序是编译器或处理器为提高程序性能而做的优化
1.编译器优化冲排序(编译器优化)
2.指令级并行重排序(处理器优化)
3.内存系统的重排序(处理器优化)
as-if-servial
无乱怎么进行重排序,代码的执行结果应该与代码顺序执行的结果保持一致

不可见的原因
1.线程的交叉执行
2.重排序集合线程的交叉执行
3.共享变量未及时更新

synchronized的解决方案
1.原子性
2.可见性(synchronized本身就会保证这一点)

volatile的解决方案
深入来说:通过加入内存屏障和禁止重排序优化来实现
对volatile变量执行写操作时,会在写操作后加入一条store屏障指令
对volatile变量执行读操作时,会在读操作后加入一条load屏障指令
通俗来说:volatile变量在每次被线程访问时,都强迫从主内存中重读该变量的值,当该变量发生变化时,又会强迫线程将该变量的值刷新到主内存中
volatile不能保证原子性
多线程中安全使用volatile变量,必须满足
1.对变量的写入操作,不能依赖当前的值
不满足: 如number++ count*=count等
满足:boolean变量,记录温度变化
2.该变量没有包含在具有其他变量的不变式中
不满足:不变式 low<up

比较synchronized与volatile
执行速度
synchronized会阻塞线程,而volatile不会
安全性
synchronized保证操作的原子性和可见性,而volatile只能保证可见性

注意:共享变量的值定义为private
注意:transient也可以保证可见性,如在集合中的modCount(修改的次数,set不记录)被定义为transient

java并发包
Callable
类似Runnable 执行耗时操作,并可以将计算结果作为返回值,同时还可以抛出异常,Runnable则不能
Future 可以拿到这个返回值(get方法)
用法
new Thread(future).start()

线程的介绍就先到这了,更详细的请戳我的多线程系列

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

推荐阅读更多精彩内容