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

个人网站 域名泉州做网站哪家好

个人网站 域名,泉州做网站哪家好,公众信息帮竞彩网站做维护吗,稿定设计简单好用的在线设计平台文章目录 一个线程不安全的案例造成线程不安全的原因抢占式执行多个线程修改同一个变量修改操作不是原子的内存可见性问题指令重排序问题 如何让线程变得安全#xff1f;加锁synchronized volatile 一个线程不安全的案例 题目#xff1a;有较短时间让变量count从0加到10_000… 文章目录 一个线程不安全的案例造成线程不安全的原因抢占式执行多个线程修改同一个变量修改操作不是原子的内存可见性问题指令重排序问题 如何让线程变得安全加锁synchronized volatile 一个线程不安全的案例 题目有较短时间让变量count从0加到10_0000 解决方案我们创建两个线程分别让count加5_0000次 结果count 10_0000 class Count{public int count 0;public void increase(){count;}} public class Demo {//验证线程不安全问题public static void main(String[] args) {Count count1 new Count();// 操作同一个变量Thread thread1 new Thread(() - {for (int i 0; i 50000; i){count1.increase();}});Thread thread2 new Thread(() - {for (int i 0; i 50000; i){count1.increase();}});thread1.start();thread2.start();try {thread1.join();} catch (InterruptedException e) {e.printStackTrace();}try {thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(count1.count); // 100000} }造成线程不安全的原因 抢占式执行 操作系统调度线程的时候是一个“随机”的过程当两个线程都参与调度的时候谁先谁后不确定。 多个线程修改同一个变量 线程之间是“并发执行的”当多个线程修改同一个变量时多个线程同时获取到了变量值。某一个线程修改了变量修改的结果不能被其他线程知道其他线程还会修改原先获取到的值导致结果错误。 如果修改的是不同的变量线程之间独立执行不会出现问题。 修改操作不是原子的 count操作底层是三条指令在CPU上完成的 load把内存中的值读到CPU寄存器中 addcount1 save把寄存器的值写回内存 由于这三条指令不是原子的两个线程在执行时就会有不同的执行顺序 在这些执行顺序下都会使count没有正确的使最终结果出错。 内存可见性问题 JVM优化引入的BUG。例如两个线程在操作同一个变量一个线程读并且比较一个线程修改。假设读操作非常频繁的情况下比较操作也会非常的频繁。但是读是从内存中读比较是在CPU里比较。比较的速度远远大于读的速度。而且每次读到的值还一样这时编译器就会大胆优化只读取一次后面就不从内存中读了。每次比较都和前面读取到的值比较不和内存中的值比较。这时另一个线程把内存中的值修改了但是这个线程比较的还时原来的值就会有问题。 指令重排序问题 JVM优化引入的BUG。由我们自己写的代码在大多数情况下的执行流程中指令的执行顺序往往都不是最优选择即没有使运行速度达到最快。因此JVM在编译时就会在逻辑等价的前提下对我们的指令进行重新排序使代码的运行速度变快。 这样的优化在单线程时是没有问题的。但是在多线程的情况下线程之间是抢占式执行的哪条指令先执行哪条指令后执行不确定就可能有问题。 如何让线程变得安全 “抢占式执行”是线程调度的基本方式我们无法干预。 “多个线程修改同一个变量”我们在特定场景下就是得修改同一个变量也无法改变。 “操作不是原子的”我们保证线程安全的主要方式通过synchronized加锁。 “内存可见性”“指令重排序”JVM优化的问题。使用volatile解决 加锁 锁具有独占的特性。如果当前锁还没有被加上加锁操作就能成功如果锁已经被人加上了加锁操作就不能成功会进入阻塞等待的状态。即加锁操作会让”并发执行“变成”串行执行“ 注 处于同一个规则所有线程都会加锁的情况下只有获取到锁才能执行相关操作。一个线程加锁另一个线程不加锁。这样不能保证线程安全。 因为它俩没有采用同一个规则办事儿不会产生锁竞争。 synchronized 加锁操作是通过synchronized关键字来实现的只要对同一个对象加锁就会产生“锁竞争”。而synchronized有三种用法 synchronized修饰代码块 synchronized修饰代码块时必须指定锁对象。如果锁对象是this即对当前对象加锁。 像下面的代码count调用了increase就是对count加锁对同一个对象加锁会出现“锁竞争” public void increase(){synchronized (this){count;}}Count count new Count();Thread thread1 new Thread(() - {for (int i 0; i 50000; i){count.increase();}});Thread thread2 new Thread(() - {for (int i 0; i 50000; i){count.increase();}});当两个线程针对两个对象加锁时不会产生“锁竞争”不会阻塞等待。 public void increase(){synchronized (this){count;}}Count count1 new Count();Count count2 new Count();Thread thread1 new Thread(() - {for (int i 0; i 50000; i){//对count1加锁count1.increase();}});Thread thread2 new Thread(() - {for (int i 0; i 50000; i){//对count2加锁count2.increase();}});synchronized修饰普通方法 synchronized修饰普通方法时相当于是锁this对象只要是同一个对象调用到这个方法都会产生“锁竞争”。 public synchronized void increase(){count;}Count count new Count();Thread thread1 new Thread(() - {for (int i 0; i 50000; i){ count.increase();}});Thread thread2 new Thread(() - {for (int i 0; i 50000; i){count.increase();}});synchronized修饰静态方法 静态方法是随着类加载而加载的而且只加载一次所以静态方法是和类绑定在一起的只有一份。 public static Object locker new Object();public void increase(){synchronized(locker){count;}}Count count new Count();Count count1 new Count();//count和count1都是Count类的对象 里面的静态方法是同一个。//所以它俩虽然是不同的对象 但是也会产生“锁竞争”Thread thread1 new Thread(() - {for (int i 0; i 50000; i){ count.increase();}});Thread thread2 new Thread(() - {for (int i 0; i 50000; i){count1.increase();}});Count.class是对类对象加锁而类也只有一份儿。静态方法也是只有一份儿所以它们俩也会产生“锁竞争” public static Object locker new Object();public void increase(){synchronized(locker){count;}}public void increase1(){synchronized(Count.class){count}}Count count new Count();Count count1 new Count();//count和count1都是Count类的对象 类只有一个静态方法也是只有一个。它们俩绑定在一起//所以它俩虽然是不同的对象 但是也会产生“锁竞争”Thread thread1 new Thread(() - {for (int i 0; i 50000; i){ count.increase();}});Thread thread2 new Thread(() - {for (int i 0; i 50000; i){count1.increase();}});volatile public volatile int count 0;volatile只有一个用法就是修饰变量表示该变量的值必须从内存中读取不能从缓存中读取。 即volatile禁止了编译器优化避免了直接读取CPU寄存器中缓存的数据而是每次都读取内存。 但是volatile并不能保证是操作是原子性的因此它只适合用于一个线程读一个线程修改的场景。不适合用于两个线程都修改的场景。 谈到volatile就会联想到JMMJava Memory ModelJava内存模型。 在JMM中引入了新的术语 工作内存work memory即CPU寄存器缓存 主内存(main memory)真正读取的内存 站在JMM的角度看待volatile 正常程序的执行过程中先会把主内存的数据加载到工作内存中再进行计算处理。编译器优化可能会导致不是每次都会真正的读取主内存而是直接读取工作内存中的缓存数据就可能导致内存可见性问题。volatile起到的效果就是保证每次读取数据都是真的从主内存中重新读取。
http://www.pierceye.com/news/161948/

相关文章:

  • 浙江省互联网建设网站python开发手机网站开发
  • 做网站需要多少钱一年动漫制作技术是学什么
  • 刘洋网站建设 够完美保卫处网站建设
  • 个人怎么申请营业执照北京朝阳区优化
  • 免费的舆情网站不用下载直接打开江西城乡建设网站
  • 那些网站是做金融行业网站主目录权限配置
  • 本地网站做不大wordpress 安全设置
  • 宁波教育平台网站建设广告行业怎么找客户
  • php企业网站开发实验总结商城网站建设模板
  • 单词优化和整站优化建设银行的网站特点
  • 厦门淘宝网站设计公司wordpress大前端dux5.2
  • 淮南网站seo网络信息发布平台
  • 网站自己做流量如何查询网站被百度收录情况
  • 网络营销网站源码做网站中怎么设置单张图片
  • 怎么做淘宝客网站网站定位代码
  • 自己给网站做logo卓成建设集团有限公司网站
  • 西宁建设网站软件徐州集团网站建设公司
  • 做网站卖设备找哪家好百度智能云windows系统服务器建站
  • 长沙企业做网站专门查企业信息的网站
  • 比较权威的房产网站百度网盘官网登陆入口
  • 金融商城快捷申请网站模板下载安全电子商务网站设计
  • 公司网站建设重要性天津建设交培训中心网站
  • 成都网站制作东三环论文一区二区三区是什么意思
  • 织梦图片瀑布流网站模板成都大型网站维护公司
  • 企业信息网站wordpress怎么调用m3u8视频
  • 前端怎么接私活做网站中文h5编程工具
  • wordpress模板 站长营销型网站开发
  • 广西南宁市住房和城乡建设局网站网络平台怎么建
  • 徐州提供网站建设报价表手机微网站怎么做
  • 建设汽车行业网站网站建设规划书百度文库