技术中心

这里象征着我们的态度和能力

>java内置线程同步机制
作者:中国IT实验室    来源:中国IT实验室    发布时间:2012-01-01      浏览次数:5992
分享到:
欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

  Java语言内置了多线程支持,同时提供了很好用的线程同步机制。

  每个Java对象都有一个锁(jdk文档中称为object monitor),这个锁在很多地方都有使用。

  1. synchonized方法和synchonized块

  线程X中调用a对象的synchonized方法func(),自动等待并获取要获取a对象的锁,方法退出(正常退出或抛出异常退出)时自动释放a对象的锁。这里有个很好的特性,获取和释放锁都是自动进行的,不会出现忘记释放锁的情况。

  synchonized块是synchonized方法的扩展,它获取的是synchonized块所指定的对象的锁,synchonized方法相当于synchonized(this)。synchonized块的好处是可以将一个对象作为锁在多个地方使用。

  2. Object类的wait() notify() notifyAll()

  如果说synchonized是用来做线程同步的,那么Object类的wait() notify() notifyAll()就是用来做线程间通信的。

  需要特别注意的是,调用这3个方法之前都要在对应对象的synchonized方法或synchonized块中进行,否则会出现异常。

  调用对象m的wait()会使当前线程Y等待,4中情况可能使等待退出:a.wait超时 b.m的notify被调用 c.m的notifyAll被调用 d.线程Y的interrupt被调用。处理第一种都会有InterruptedException异常抛出,因此wait调用需要catch InterruptedException.

  常见用法:生产者消费者队列,消费者发现队列q为空时调用q.wait(),生产者向队列加入一个元素后调用q.notifyAll(),此时消费者可以被唤醒

  3. Thread类的sleep() interrupt() isInterrupt() interrupted()

  可以调用它Thread.sleep()使当前线程睡眠一段时间。

  线程Z在睡眠、等待事件、等待IO时,外部可能需要提前唤醒线程Z,这种情况下调用Z的interrupt()即可将它从等待中唤醒,Z线程会收到InterruptedException.

  值得一提的是,如果线程在正常工作(非上述的等待状态,如在一个循环中做加法),interrupt()是不能打断它的工作的。如果线程需要知道外界是否调用interrupt(),可以通过isInterrupt()检查。而interrupted()是检查当前线程的isInterrupt()状态并清除状态。

  4. volatile变量

  volatile变量解决的是这样一个问题:Java中多个线程共享的一个变量,某个线程更新该变量后,其他线程不能保证立即读到最想新的值。

  将某个变量声明为volatile,可以保证某个线程对它的修改,后续其他线程读到的都是最新值。

  5. atomic变量

  atomic变量解决的是另一个问题:Java不保证多线程同时写共享的long, double是原子的,可能出现奇异的值。另外,++或――这种其实是两步的操作就更不能保证原子了。

  volatile同时有atomic变量的第一个特性,写原子的。

4000-880-989
(24小时热线)
联系客服
微信公众号

官方公众号

小程序

©2008-2022 CORPORATION ALL Rights Reserved. 昆明奥远科技有限公司版权所有 滇ICP备09003328号-1 滇公网安备 53011102000818号 增值电信业务经营许可证号:滇B2-20110045
昆明那家网络公司好,新媒体运营,网站优化,网络推广,网站建设,网页设计,网站设计,网站推广,云南网站公司,昆明新媒体公司,云南网红主播,昆明SEO公司,昆明网站建设,昆明网络推广,昆明网站优化,昆明网站推广,红河网站建设,大理网络公司,曲靖网络公司,丽江网站设计,昭通网络公司,保山大数据服务,智慧高速建设,智慧校园服务,云南IDC服务商,网络安全测评,等保测评,网站关键词排名优化服务,服务客户尽超2000余家,一切尽在奥远科技,服务电话:13888956730