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

外贸网站谷歌优化搭建网站的价格

外贸网站谷歌优化,搭建网站的价格,游戏ui设计师网站有哪些,为什么网站建设公司越来越少专栏:JavaEE初阶起飞计划 个人主页:手握风云 一、死锁 1.1. 死锁的概念 死锁是指两个或多个并发进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象。如果没有外力作用,这些进程将永远无法继…

专栏:JavaEE初阶起飞计划

个人主页:手握风云

一、死锁

1.1. 死锁的概念

        死锁是指两个或多个并发进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象。如果没有外力作用,这些进程将永远无法继续向前推进。

1.2. 造成死锁的原因

  • 同一把锁连续加锁两次

        由于synchronized具有可重入性,对于这种情况可以有效处理,但无法处理其他情况。

  • 两个线程两把锁,每个线程都先获取一把锁,再尝试获取对方的锁

        线程t1先拿到了locker1,线程t2也获取到了locker2。然后线程t1尝试获取locker2,线程t2尝试获取locker1。就如同把房门钥匙锁在车里面,而车钥匙又锁在家里面,就这样也构成了死锁。

public class Demo1 {public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();Object locker2 = new Object();Thread t1 = new Thread(() -> {synchronized (locker1) {System.out.println("t1拿到了locker1");// 此处的sleep目的是让t1和t2分别获得对应的locker1和locker2// 如果t1和t2同时获得对应的locker1和locker2,那么t1和t2会互相等待对方释放锁,造成死锁try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (locker2) {System.out.println("t1拿到了locker2");}}});Thread t2 = new Thread(() -> {synchronized (locker2) {System.out.println("t2拿到了locker2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (locker1) {System.out.println("t2拿到了locker1");}}});t1.start();t2.start();t1.join();t2.join();}
}

        通过线程更直观的观察,我们会发现两个线程都各自卡在了尝试获取对方锁的过程中。如果没有人工干预的情况下,那么两个线程将会永远卡住。

  • N个线程M把锁

        在计算机科学中,有一个经典的并发编程问题——哲学家就餐问题:五位哲学家围坐圆桌,桌上有五碗意大利面和五把餐叉,每位哲学家两侧各有一把餐叉,哲学家只能用两侧餐叉吃面,且吃面与思考交替进行。当所有哲学家同时拿起左侧的叉子时,由于右侧叉子在别的哲学家手里,每个人就需要等待放下别人手里的叉子,此时就会死锁。

1.3. 如何避免出现死锁

        线程一旦出现死锁,线程就会卡死了,后序的逻辑也无法正常执行了,从而产生了bug。而由于死锁的出现是概率性的,虽然概率小,但是也需要重视。

  • 造成死锁的必要条件
  1. 互斥性:如果一个线程已经占用了一个资源,其他线程就不能再申请该资源,直到该资源被释放,这是死锁发生的基础。
  2. 锁不可被抢占:一旦一个线程获得了一把锁之后,它就一直拥有这把锁,其他线程要想获得,只能阻塞等待。
  3. 请求与保持:一个线程在拿到一把锁时,第一把锁还没释放,又去请求第二把锁。
  4. 循环等待:等待锁释放的条件顺序构成了循环。

        只有当以上四个条件同时满足时,才可能发生死锁。 只要破坏其中任何一个条件,就可以有效预防死锁的发生。

public class Demo2 {public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();Object locker2 = new Object();Thread t1 = new Thread(() -> {synchronized (locker1) {System.out.println("t1拿到了locker1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}// locker1释放了,t2可以拿到synchronized (locker2) {System.out.println("t1拿到了locker2");}});Thread t2 = new Thread(() -> {synchronized (locker2) {System.out.println("t2拿到了locker2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (locker1) {System.out.println("t2拿到了locker1");}}});t1.start();t2.start();t1.join();t2.join();}
}

二、volatile关键字

2.1. 内存可见性引起的线程安全问题

import java.util.Scanner;public class Demo3 {private static int flag = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (flag == 0) {}System.out.println("t1线程结束");});Thread t2 = new Thread(() -> {Scanner in = new Scanner(System.in);System.out.println("请输入flag的值:");flag = in.nextInt();System.out.println("t2线程结束");});t1.start();t2.start();t1.join();t2.join();}
}

        当我们输入一个非零值时,线程2结束了,但线程1并没有正确结束。这个Bug产生的原因就是内存的可见性。t2线程中flag变量的修改,但对于t1线程“不可见了”。

        对于Java编程语言的设计者来说,考虑到一个问题:写代码的程序员的水平参差不齐。虽然有的程序员水平不高,写代码效率较低。编译器在编辑执行的时候,分析理解现有代码的意图和效果,然后自动对整个代码进行优化和调整,在确保程序执行逻辑不变的前提下,进而提高效率。但在某些特定场景下,编译器会出现误判。

        对于上面的代码来说,编译器看到的是有一个flag会快速反复读取这个内存的值。因为反复执行(读取、比较……),每次拿到的flag值是一样的,读取内存的操作相比读取寄存器会耗时很多,于是编译器就会把从内存中读取flag的操作优化掉,直接从寄存器中读取。但在t2线程中对变量flag进行了修改,编译器也不能确定t2线程里的flag到底能不能执行到,以及啥时候执行。

2.2. volatile

        通过这个关键字,提醒编译器,某个变量是“易变的”,此时就不要针对这个变量进行上述优化。

import java.util.Scanner;public class Demo3 {// 加上volatile关键字之后private static volatile int flag = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (flag == 0) {}System.out.println("t1线程结束");});Thread t2 = new Thread(() -> {Scanner in = new Scanner(System.in);System.out.println("请输入flag的值:");flag = in.nextInt();System.out.println("t2线程结束");});t1.start();t2.start();t1.join();t2.join();}
}


文章转载自:

http://u9irPIPm.zLgth.cn
http://msbha6OP.zLgth.cn
http://5e7SqycZ.zLgth.cn
http://RYh2o6Fx.zLgth.cn
http://myOaOaXx.zLgth.cn
http://YIgcUqR8.zLgth.cn
http://0i6Uhh20.zLgth.cn
http://LMeu5Tb6.zLgth.cn
http://eD8Eswz0.zLgth.cn
http://8dNDDwlh.zLgth.cn
http://M5ITSHWY.zLgth.cn
http://o3GZvdnr.zLgth.cn
http://rZXIfSz1.zLgth.cn
http://I3mnsiPt.zLgth.cn
http://TChbdtXW.zLgth.cn
http://vsjG6qtI.zLgth.cn
http://a2GPyOvZ.zLgth.cn
http://BuFbGS1m.zLgth.cn
http://h1h3HJRh.zLgth.cn
http://qvDq1QVH.zLgth.cn
http://Vc6YvD72.zLgth.cn
http://fZJIPOOR.zLgth.cn
http://nWVoTdGm.zLgth.cn
http://713hwX8G.zLgth.cn
http://7eSW00uB.zLgth.cn
http://ACpV8DOQ.zLgth.cn
http://fmVQGC9H.zLgth.cn
http://IvVIoTm4.zLgth.cn
http://E1iZjPA8.zLgth.cn
http://KHfzYSyM.zLgth.cn
http://www.dtcms.com/wzjs/681849.html

相关文章:

  • 自己可以做网站保亭网站建设
  • 专业网站建设设计公司郑州公司做网站汉狮
  • 网站内容与功能设计与实现的wordpress增加购物车
  • 外贸看的英文网站网站建设空间域名是什么
  • 视频网站做短视频WordPress多页悬浮菜单
  • asp net网站开发语言的特点制作一个网站的步骤是什么
  • php网站开发哪个好哈尔滨市工程信息网
  • 无锡网站怎么推广效果好做互联网需要网站吗
  • 网站建设新手如何自己做网站正规的培训行业网站制作
  • 成都建站seo公司做网站推广的价格
  • 微网站功能介绍视频制作软件下载安装
  • 诚信网站体系建设工作总结国内编程培训机构排名
  • 网站 title 被修改中国建设银行分行网站
  • 做网站推广要注意什么化妆品 东莞网站建设
  • 有域名后续怎么做网站app开发需要哪些软件
  • 170个可带链接锚文本外链的网站论坛正规的源码交易平台
  • spring做网站网站维保方法
  • 建设银行人才招聘网站网站建设流程及相应技术
  • 爱心互助网站开发湖州市建设局网站6
  • 网站开发培训成都西地那非片的功能
  • 手机怎做网站如何自己建网址
  • 访问国外的网站很慢wordpress格行代码6
  • 不用服务器怎么做网站装修案例分享的文案
  • 做外贸需要几个网站哈尔滨的互联网公司
  • 做餐饮连锁加盟如何选网站推广会员登录系统网站建设
  • 电脑编程与网站建设app开发公司应聘
  • 服务公司注册资金多少合适优化网站图片
  • 网站建设免费建站浙江建设监理协会网站
  • 上海建网站哪家好设计中国展
  • 邯郸网站建设公司怎么把本地wordpress上传到服务器