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

做网店好还是网站职业培训机构有哪些

做网店好还是网站,职业培训机构有哪些,网站建设公司的公司,网站做关键词各位看官,大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连,小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习:wait和notify : 避免线程饿死(以及votile内存可见性和指令重排序问题) …

各位看官,大家早安午安晚安呀~~~

如果您觉得这篇文章对您有帮助的话

欢迎您一键三连,小编尽全力做到更好
欢迎您分享给更多人哦

今天我们来学习:wait和notify : 避免线程饿死(以及votile内存可见性和指令重排序问题)

目录

4.volatile

4.1.保证内存可见性

4.2.:指令重排序问题(我们放到下一篇博客来讲解)

5.wait,notify

5.1.wait方法的使用

5.2.notify方法的使用

6.wait和notify可以避免线程饿死


4.volatile

volatile的两个作用(其实都是不让编译器做出多余的优化,对我们的程序产生bug)

1.保证内存可见性

2.解决指令重排序问题

4.1.保证内存可见性

序言:

计算机运行的程序往往要访问数据,这些依赖的数据一般都被读取到了内存里面(譬如我们定义的一个变量就是在内存里面)

就譬如count++;cpu先把count读到cpu寄存器里面再进行++;

但是!  cpu其他的操作都很快,但是读内存就比较慢(读硬盘更慢,快慢都是相对的)

因此,为了提高效率编译器就会做出优化,把一些要读内存的操作优化成读寄存器。减少读内存的次数,就提高了整体程序的效率~~

public class Demo1 {private static int isQuit = 0;public static void main(String[] args) {Thread t1 = new Thread(() ->{while(isQuit == 0){// 一直循环啥也不不干}System.out.println("t1 退出");});Thread t2 = new Thread(()->{System.out.println(" 请输入isQuit的值");Scanner scanner = new Scanner(System.in);isQuit = scanner.nextInt(); // 输入不为0的值,使t1线程结束});t1.start();t2.start();}
}

我们发现我们明明输入非0值但是t1线程就是没结束为什么呢?

所以说volatile就是一个优化方法,我们给isQuit前面用volatile修饰就可以避免这样的问题了

       在多线程环境下,编译器对于是否要进行这样的优化,判定不一定准.这个时候就需要程序猿通过 volatile 关键字,告诉编译器,这个情况不用优化!!!优化,是算的快了,但是算的不准了)

 总之:编译器,也不是万能的.也会有一些自己短板的地方.此时就需要程序猿进行补充了.
只需要给 isQuit加上 volatile 关键字修饰,此时编译器自然就会禁止上述优化过程。

还有另一种方式,也可以避免这样的问题(再加上一个时间更长的操作,让读内存不那么慢了(相对来说)哈哈)

public class Demo1 {private static int isQuit = 0;public static void main(String[] args) {Thread t1 = new Thread(() ->{while(isQuit == 0){// 一直循环啥也不不干try {   //就多加了一个sleepThread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t1 退出");});Thread t2 = new Thread(()->{System.out.println(" 请输入isQuit的值");Scanner scanner = new Scanner(System.in);isQuit = scanner.nextInt(); // 输入不为0的值,使t1线程结束});t1.start();t2.start();}
}

此时没加 volatile, 但是给循环里加了个 slee

线程是可以退出了
加了 sleep 之后, while 循环执行速度就慢了.由于次数少了,load (读内存)操作的开销,就不大了.因此,优化也就没必要进行了.
没有触发 load的优化,也就没有触发内存可见性问题了.
到底啥时候代码有优化,啥时候没有?也说不清楚,但是使用 volatile 还是更靠谱的选择!!

4.2.:指令重排序问题(我们放到下一篇博客来讲解)

5.wait,notify

每个线程都是独立的执行流

想法:

由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知.(join是决定了线程结束的先后顺序)
但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序.

完成这个协调工作, 主要涉及到三个方法

wait() / wait(long timeout): 让当前线程进入等待状态.

notify() / notifyAll(): 唤醒在当前对象上等待的线程.

注意: wait, notify, notifyAll 都是 Object 类的方法.

5.1.wait方法的使用

wait()方法要做的事情:

  1. 释放当前的锁(前提是你得有锁,不然怎么释放)
  2. 线程进入阻塞
  3. 线程被唤醒, 重新尝试获取这个锁.

wait 要搭配 synchronized 来使用. 脱离 synchronized 使用 wait 会直接抛出异常.

  public static void main(String[] args) throws InterruptedException {Object locker = new Object();System.out.println("wait 之前");locker.wait();  //没加锁,会抛出异常System.out.println("wait 之后");}

wait 结束等待的条件:

1.其他线程调用该对象的 notify 方法.

2.wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本, 来指定等待时间).

3.其他线程调用该等待线程的 interrupted 方法, 导致 wait 抛出 InterruptedException 异常.

接下来我们看一个代码

  public static void main(String[] args) throws InterruptedException {Object locker = new Object();System.out.println("wait 之前");locker.wait();  // 只要一般涉及阻塞的方法都会抛出异常//locker这个对象只要不notify,这个线程就一直处于waiting状态(加了等待时间就不会了)System.out.println("wait 之后");}

运行结果以及jconsole观察到的结果(这个程序就一直等待,死等(除非有等待时间))

5.2.notify方法的使用

我们以代码举例:创建三个线程都去wait,主线程notify唤醒(随机的)

  public static void main(String[] args) throws InterruptedException {Object locker = new Object(); // 公用一个锁对象Thread t1 = new Thread(() ->{synchronized (locker){try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t1 醒了");});Thread t2 = new Thread(()-> {synchronized (locker){try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t2 醒了");});Thread t3 = new Thread(()->{synchronized(locker){try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t2 醒了");});t1.start();t2.start();t3.start();System.out.println("唤醒其中一个线程");Thread.sleep(1000);  // 确保其他线程已经处于waiting状态synchronized(locker){locker.notify();// 也要记得加锁呀,不然咋释放锁}}

结果:可以看到随机一个线程被唤醒,其他线程在waiting状态

如果是notifyAll方法呢?(三个线程都被唤醒了,但是第一个拿到锁的线程如果执行的任务比较多,另外两个线程会处于BLOCKED状态(由于锁竞争导致的阻塞))

6.wait和notify可以避免线程饿死

先介绍synchronized是可重入锁,什么是可重入锁呢?一个线程对一个对象连续加锁两次不会出现死锁。就譬如这个按理说会出现死锁但是我是可重入的所以不会形成死锁

说到死锁:举一个例子()(这样一个线程想要多把锁,进而形成环,直接卡死就会导致死锁)

说到环就想到哲学家问题

总结:四个成因(破坏一个就解除)

 class Singleton {private static Singleton instance = new Singleton();public static Singleton getInstance(){  // 一定要是静态方法,不然一开始别人都拿不到这个对象,又没办法调用这个方法,岂不是贻笑大方return instance;}private Singleton(){} // 啥也不用干,也干了呀,把构造方法给藏起来了
}public class SingletonDemo{public static void main(String[] args) {Singleton singleton = new Singleton();}
}

上述就是wait和notify : 避免线程饿死(以及votile内存可见性和指令重排序问题)的全部内容啦

能看到这里相信您一定对小编的文章有了一定的认可。

有什么问题欢迎各位大佬指出
欢迎各位大佬评论区留言修正~~

您的支持就是我最大的动力​​​!!!

http://www.dtcms.com/wzjs/153677.html

相关文章:

  • 在线做任务的网站有哪些软文如何推广
  • 送给做网站的锦旗语昆明seo技术培训
  • wordpress 富文本编辑器成都百度推广和seo优化
  • 随州学做网站的学校搜狗推广管家
  • 网站开发合同 中英文百度营销登录平台
  • wordpress外链转内链云优化软件
  • 网站要素的优化设计电子商务平台建设
  • 政府网站建设内容规划网络公司网络营销推广方案
  • 网上做网站广告投放网络营销策划书论文
  • 部队网站建设优化网站哪个好
  • 技术支持:洛阳网站建设佛山seo外包平台
  • 如何c2c网站建设河北网络推广技术
  • wordpress 管理菜单seo排名优化是什么意思
  • 投资者网站建设营销策划案的模板
  • 建设网站网站海南百度推广总代理商
  • APP网站开发联系电话免费seo推广计划
  • 重庆网站建设公司排名长沙seo招聘
  • 做网站需要发票吗网络营销包括几个部分
  • 网站建设与维护 出题百度推广账号怎么注册
  • 重庆网站建设备案产品网络推广方式
  • 手机兼职赚钱东莞外贸优化公司
  • 网站主办单位变更信息流广告代运营
  • 值得相信的西安网站开发关键词优化公司排名榜
  • 怎么把自己做的网站放到公网上网店网络营销策划方案
  • 东莞哪家网站营销公司好软文推广发布
  • 网站推广与维护设计方案seo怎么做教程
  • 做网站用什么编程语言舆情监控
  • 武汉做网站的培训机构广州搜索排名优化
  • 云南电商网站开发电脑优化大师官方免费下载
  • 网页设计与制作自考真题电子商务seo名词解释