当前位置: 首页 > news >正文

快站wordpress十大搜索引擎排名

快站wordpress,十大搜索引擎排名,高端建筑物图片,郑州网站高端网站设计阿华代码,不是逆风,就是我疯,你们的点赞收藏是我前进最大的动力!!希望本文内容能够帮助到你! 目录 一:问题引入 二:问题深入 1:举例说明 2:图解双线程计算…

阿华代码,不是逆风,就是我疯,你们的点赞收藏是我前进最大的动力!!希望本文内容能够帮助到你!

目录

一:问题引入

二:问题深入

1:举例说明

2:图解双线程计算

​编辑

3:线程不安全原因的总结

(1)根本原因

(2)代码结构

(3)直接原因

(4)内存可见性问题

(5)指令重排序问题

5:解决问题的思路

(1)针对根本原因解决

(2)针对代码结构的原因解决

(3)针对直接原因——加锁

三:synchronized关键字(加锁)

1:synchronized

2:核心内容

(1)含义

(2)代码解释:

①“锁竞争”

②“加锁”

③“同一对象”

④“都要加锁”

3:变式

变式①:this

变式②: 类名.class

变式③:public前加synchronized

变式④:static方法前加synchronized(少见)


一:问题引入

用多线程,让计数器自增到1_0000

package thread;public class ThreadDemon19 {private static long count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {count ++;}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {count ++;}});t1.start();t2.start();t1.join();t2.join();System.out.println("双线程的计算结果是:"+count);}}

package thread;public class ThreadDemon20 {private static long count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 1_0000; i++) {count ++;}});t1.start();t1.join();System.out.println("单线程的计算结果是:"+count);}}

 6ac3e10de1ea41f98d6f5891e5102852.png958d008681f84d10bceb10abe287dbd0.png

通过上述代码的举例,我们发现解决同一个问题,怎么最后的结果会不一样呢,真是奇了怪了。

二:问题深入

结果不一样,猜测是循环自增代码这一块出现问题

1:举例说明

我们知道cpu可以读取指令,解析指令,执行指令此处我们重点关注执行指令

count++,实际由三个指令构成的

(1)load:从内存中读取数据到cpu的寄存器当中

(2)add:把寄存器当中的值+1

(3)save:把寄存器当中的值写回到内存中

2:图解双线程计算

83b697bde121487f9842153d9f3a0844.png

c078365d354b4dce8eeaa2523e0ba043.png

t1,t2双线程的运行下,可能同一次读取操作中,t1和t2都读取到的是没有自增的数

可以通俗的理解,本来t1由数字1自增后到2,t2读取的应该是2,然后自增到3.

但是如果t2 在 t1把自增后的2 save回寄存器中  之前  读取的话 t2读到的就是1,最后只能自增到2

(可以理解成被覆盖了)

所以这就出现了矛盾(计算的数据越小矛盾越小,因为cpu运行速度很快,可能第一个线程运行结束了,第二个线程还没有开始运行)

(以上可以画出无数种情况,比如t1线程自增了2次,3次,t2线程才执行了1次。)(这就是线程的随机调度和抢占式执行)

3:线程不安全原因的总结

(1)根本原因

是线程的“抢占式执行和随机调度”

(2)代码结构

多个线程可以修改同一变量

(3)直接原因

是上述多线程修改变量这一操作并不是“原子性”的,而是可拆分的(就像我们上面画的图),这里就是操作系统底层结构的问题了

(4)内存可见性问题

(5)指令重排序问题

(4)(5)条上述代码没有涉及,我们后续再详细引入

5:解决问题的思路

为了确保结果的正确,我们得确保第一个线程save了过后,第二个线程再去load。这时第二个线程load到的数据才是自增过后正确的数据

(1)针对根本原因解决

不可行。如果要修改线程的“抢占式执行和随机调度”这一机制的话,就得修改操作系统中的内核,相当于是重新写了一个“新的系统”

(2)针对代码结构的原因解决

有些地方,代码结构可以进行修改,但是有些地方不可以,视情况而论

(3)针对直接原因——加锁

count++,由三个指令完成,我们如果给这三个指令打包成一个整体的话就可以避免线程出现问题了,也就是“加锁”

三:synchronized关键字(加锁)

1:synchronized

关键字:synchronized(对象){加锁内容};

注:synchronized的加锁依赖于对象

2:核心内容

(1)含义

如果第一个线程对某个对象上锁之后,第二个线程要想对同一个对象上锁,就必须等第一个线程释放锁,此时第二个线程是处于BLOCKED阻塞状态

package thread;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-09-21* Time: 15:27*/
public class ThreadDemon21 {private static long count = 0;public static void main(String[] args) throws InterruptedException {Object locker = new Object();//创建一个object对象Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized (locker){  //锁到object这个对象上count++;}}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized(locker){   //锁到object这个对象上count++;}}});t1.start();t2.start();t1.join();t2.join();System.out.println("计算结果是:" + count);}}

34ecb5cf59ec417d9278c9f3ee3dd8c0.png

(2)代码解释:

8265d6d44fe34545b81cad721dd02fb4.png

①“锁竞争”

通过“锁竞争”让让第二个线程无法插入到第一个线程的执行指令当中。

②“加锁”

“加锁”就是把count++中三个指令(load,add,save)打包成一个“原子性”的操作(最小单位的操作,再也不可分割了)

③“同一对象”

加锁的对象不同,“锁竞争”就不会发生,线程安全问题依旧存在

④“都要加锁”

如果第一个线程加锁,第二个线程不加锁,“锁竞争”也不会发生,线程安全问题依旧存在

3:变式

变式①:给this加锁

this指向的还是同一个对象,t1和t2依旧会产生“锁竞争”

package thread;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-09-21* Time: 15:27*/
class Test{public long count = 0;public void add(){synchronized (this){count++;}}}
public class ThreadDemon22 {public static void main(String[] args) throws InterruptedException {Test test = new Test();Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {test.add();}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {test.add();}});t1.start();t2.start();t1.join();t2.join();System.out.println("计算结果是:" + test.count);}
}
变式②: 类名.class

获取到当前类的对象,类对象包含了这个类的各种信息(类名字,属性,方法.......)

0d9678cdd4cc43c980ea87a69badfdf5.png

变式③:public前加synchronized

等价写法

149e4cdcd5764beea70abfd90e40972c.png26e85566700e4e468089ca8f887ae40e.png

变式④:给类对象加锁(static)
static方法前加synchronized(少见)

7907e54c80374913a85e7238d89f2940.png16e0df5e0bd34a6791810c9b39b7ebe5.png

如果synchronized加到static方法上,就相当于给类对象加锁了

http://www.dt0577.cn/news/9653.html

相关文章:

  • 有没有网站学做总结临沂seo整站优化厂家
  • 如何将网址提交到一些权重比较高的网站网站推广优化的方法
  • 公司被其它人拿来做网站网站seo专员招聘
  • 网站开发工具大全被忽悠去做网销了
  • 个人域名 公司网站网络营销的特点举例说明
  • 如何做好网站推广方法百度投放广告
  • 免费网站提供网络营销有什么特点
  • 做华为网站的还有哪些功能怎么做好推广
  • 大连网站建设网站自己如何做链接推广
  • 网站开发工程师绩效考核表优化网站排名如何
  • 网站免费空间申请谷歌ads
  • 哈尔滨网站制作建设多少钱新塘网站seo优化
  • 做网站大概网上商城推广13种方法
  • 企业为什么要做网站合肥网站
  • 乐清做网站的公司百家号关键词排名
  • 新手自学网站南宁seo排名优化
  • 珠海网站制作网络推广站长统计app下载免费
  • b2b网站有哪些模块软件推广平台有哪些?哪个比较好
  • 四川做网站找谁重庆森林壁纸
  • 阿里云做网站流程黑马程序员培训机构官网
  • 杭州室内设计公司有哪些百度seo排名查询
  • 上海网站建设搜q.479185700上海营销seo
  • 建设网站操作可行性外贸网站建设 google
  • 传奇网页版游戏开服表北京网站快速排名优化
  • 公司网站制作设锦绣大地seo
  • 目前最新的网站后台架构技术综述青岛 google seo
  • 网站开发图书管理系统报告摘要重庆关键词优化软件
  • 有哪些用flex做的网站黑帽seo优化推广
  • 河南优化网站最新国际军事动态
  • 郴州网站建设网站百度软件优化排名