线程小白入门

第一次写博客,其实不算写,只是把自己以前的笔记粘贴过来。
今天正月初三,在家里很无聊,也不想去亲戚家尬聊,白天刷微博有想砸手机的冲动,微博上只要有好玩的段子视频下面的网友评论中一片艾特自己的男朋友或女朋友,真尼玛能秀。
开始粘笔记

线程入门

基本方法

1、 Thread.yield();停止运行的线程,并且释放线程占用的资源。
2、 sui.interrupt();设置线程的终止状态,并不停止线程。当调用线程阻塞方法时,终止状态就会被清除。
3、 Thread.stop();停止线程,给线程一种戛然而止,给正在运行的线程突然停止,一般不用此方法停止线程。
4、 MrCheng.join();使线程MrCheng线程优先运行,其他线程都要给次线程让出资源,让其先运行,
5、 lockObject.wait();线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态,进入wait set状态。https://www.cnblogs.com/hapjin/p/5492645.html
理解wait set 当一个线程不满足条件时,调用了wait()方法,就会使线程释放锁资源,进入等待区域。当拿到锁资源的线程运行完毕时,运行notifyAll()或运行notify()唤醒所有等待或者随机一个等待线程。

线程感悟

当用一个线程a启动另一个线程b时,a与b不存在父子级别关系,当a结束时,b不会随a的结束而结束。

多线程的渐进深入

线程之间的可见性:一个线程对共享变量值的修改,能够及时被其他线程看到。也就是说一个线程修改变量其他线程在用这个线程的时候,也会变化。
共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。
Java 中所有的变量都存在主内存中
每个线程都有自己的独立的工作内存,里面保存着该线程使用到的变量的副本(主内存中该变量的一份拷贝)

线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写。
不同线程之间无法访问其他线程工作内存中的变量,线程之间的变量传递需要主内存来完成。
Java内存模型(Java Memory Model)描述了java程序中各种变量(线程共享变量)的访问规则,以及在jvm中将变量存储到内存和内存中读取出变量这样的底层细节。

需要了解的多线程的知识

Producer-Consumer模型
Read-WriteLock模型
Future模型
Worker Thread模型

线程内存可见性

可见性

一个线程对共享变量值的修改能够及时的被其他线程看到。

共享变量

如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量
Java内存模型对线程的相关内存描述
所有的变量都储存在主内存里。
每个线程都有自己独立的工作内存,里面保存了该线程使用到变量的副本(主内存中该变量的一份拷贝)
线程操作共享变量规定
线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写。
不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递,需要通过主内存来完成。
实现共享变量的内存可见性必须保证两点:
1、 线程修改后的共享变量值能够及时从工作内存中刷新到主内存中
2、 其他线程能够及时的吧共享变量的最新值从主内存更新到自己的工作内存中
Java中语言层面实现可见性的关键字
1、 synchronied
2、 volatile
synchronied实现互斥锁,也就是同步,从而保证在任何时刻下,只有一个线程在执行锁内的代码,保证锁内的操作的原子性。
还有他还可以实现内存可见性,JMM关于synchronize的两条规定:1、线程解锁前,必须把共享变量的最新值刷新到主内存中去。2、线程枷锁时,必须清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(枷锁和解锁需要是同一把锁)。线程解锁前对共享变量的修改在下次枷锁时对其他线程可见。

造成共享变量在线程间不可见性问题的原因:
1、 线程的交叉执行.
2、 线程的交叉执行和重排序。
3、 共享变量更新后的值没有在工作内存和主内存中及时更新。

重排序:

是指代码的书写的顺序和实际执行的顺序不同,指令重排序是编译器或处理器,为了提高程序的性能而做的优化。
代码翻译成机器指令后,进行一下重排序,更加符合CPU的执行特点,这样才能最大限度的发挥CPU的特点。
1、 编译器的优化重排序。
2、 指令级并行重排序(处理器优化)
3、 内存系统的重排序(处理器优化)处理器对读写缓存的优化。

Synchronied

这个关键字实现原子性的原理是使加上关键字的区域线程互斥,变量的可见性的原理刷新内存。(感觉实现可见的原理都是刷新内存)

Volatile

实现可见性原理:通过加入加入内存屏障和禁止重排序优化来实现可见性。
1、 在对volatile变量执行写操作的时候,处理器会在写操作之后加入一条store的屏障指令,会把CPU写缓存区的缓存强制刷新到主内存里面,所以主内存的volatile变量就是最新的值。还会防止volatile变量前面的变量重排序到volatile之后。
2、 对volatile变量执行读操作时,会在读操作前面加入一条load的屏障指令,它会使缓冲区的缓存失效,每次在读取volatile变量的时候都会去主内存读取volatile变量值(通俗的说是线程在使用的时候都会去主内存中重新读取值)。
Volatile不能保障操作的原子性
解决方案,1、加入synchronize关键字。
二、 reentrantlock类
例子: Lock lock=new Reentrantlock();
lock.lock();
try{
n++;
}finally{
lock.unlock();
}

volatile使用场景

1、 对变量的写入操作不依赖当前值。
不可以的:number++,count=count*5;
可以的,如boolean变量。
2、 该变量没有包含在具有其他变量的不变式中
不满足:不变式low

什么是原子性?

一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行。
原子操作是不可分割的,在执行完毕不会被任何其它任务或事件中断
原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西门吹水之城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值