java并发之互斥和同步

作者: MathiasLuo | 来源:发表于2016-12-08 18:15 被阅读340次

并发在任何系统和编程语言中都有着重要的地位。

操作系统中的互斥和同步

操作系统(假设单核)中,我们可以实现同时多个进程(软件)的同时运行,其实取决于操作系统的中断,也就是一个进程在cpu上执行一个时间片后就会被中断,然后换上其它的进程上来执行,所以我们的感觉是进程都在并发的执行。或许你会问,为什么不一直执行,切换过去切换过来不消耗资源的嘛?对的,进程的切换时耗费资源,但是你得注意一种情况,就是很多时候你的进程其实并没有消耗cpu,也就是它可能正在io阻塞中,这样,cpu的切换的执行就会更加的高效,特别是那些io密集型的进程。

然而,我们在操作系统中,各个进程可能会访问同一个资源(文件)(当然,直觉上这也是不可以的),所以必须想办法去让两个或者多个进程不能同时对一个相同的资源去使用,最典型的就是不能同时去写一个文本文件。当然这里我们必须想办法让他们不能同时使用(互斥),所以操作系统的典型处理就是在内核上个屏蔽中断TSL(Test and Set Lock),软件层次的信号量和PV操作。通过这些方式,我们基本上就能够完成操作系统的互斥和同步了。


java中的互斥和同步

但是在面向编程语言的,还有一种对互斥和同步的实现,那就是管程。

管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。这些共享资源一般是硬件设备或一群变量。管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。与那些通过修改数据结构实现互斥访问的并发程序设计相比,管程实现很大程度上简化了程序设计。

对,java就是实现了管程的。

互斥 - synchronized 和 lock

java中通过了关键字synchronizedjava.util.concurrent.locks来提供互斥性。

  1. synchronized
  • synchronized关键字修饰的代码块称为同步代码块。
  • 对于每个对象来说,synchronized方法共享一个锁,也就是同时只有一个线程能够访问被synchronized标示的所有方法。
  • 类锁和对象锁,类锁指被static修饰的方法,对象就是new出来的那个,其中类锁是在class上的锁,所以所有调用的都共享同一个锁,而对象锁则不同的对象有不同的锁。
  1. **java.util.concurrent.locks **
  • 显式的加锁,常见的ReentrantLock
  • 使用显式的锁,你能够更好的控制锁的细节,及何时获取释放等。
  • 在获取ReentrantLock的同时可以interrupt(),及在获取锁的同时可以被中断。(当然在获取synchronized的时候不能够使用interrupt()中断)。

同步 - wait 和 notify

在说同步前,先讲一讲中断interrupt

在java中,interrupt()可以中断线程,然后抛出InterruptException。当然这中间也有他们的游戏规则,也就是当一个线程调用了interrupt()后,如果线程处于wait()或者sleep()中就会立即抛出异常,否则就会等他们进入阻塞的调用后再抛出。其实这个也好理解,你不能强制立即让它停止吧,当它还在活动的时候至少也得等它把手上的事做完吧。

java中通过了关键字waitnotify来提供同步性。

  1. wait
  • wait 是释放已经获取的锁,所以调用它的时候必须已经获取锁。及在synchronized锁修饰的方法中的调用。
  • sleepyield的对比,最重要的是wait释放了锁,而sleep则只是把线程挂起。
  1. notify,notifyAll
  • 调用前自己得获取了锁
  • 调用notify会唤醒一个wait过的线程,notifyAll则会唤醒所有被wait的线程。
  • notifyAll被调用的时候,只会唤醒那些等待相应的锁的任务才会被唤醒,而不是ALL。

相关文章

  • java并发之互斥和同步

    并发在任何系统和编程语言中都有着重要的地位。 操作系统中的互斥和同步 在操作系统(假设单核)中,我们可以实现同时多...

  • CAS导致的ABA问题及解决

    Java并发--非阻塞同步 CAS问题引入 在并发问题中,最先想到的无疑是互斥同步,但线程阻塞和唤醒带来了很大的性...

  • java并发编程 - 4 - Lock和Condition接口

    并发领域有2个问题,互斥和同步。互斥:同一时刻,只允许一个线程访问共享资源。同步:线程之间的协作和通信。 java...

  • 1. Java并发编程

    并发编程领域可以抽象成三个核心问题:分工、同步和互斥。 java内存模型[https://www.jianshu....

  • 程序多线程运行下怎样保证线程安全

    保证线程安全以是否需要同步手段分类,分为同步方案和无需同步方案。 1.互斥同步 互斥同步是最常见的一种并发正确...

  • 线程安全实现与CLH队列

    阻塞同步 在 Java 中,我们经常使用 synchronized 关键字来做到互斥同步以解决多线程并发访问共享数...

  • 互斥同步、锁优化及synchronized和volatile

    互斥同步 互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保...

  • Thread-Per-Message模式

    并发编程领域的问题总结为:分工,同步和互斥。同步和互斥相关问题更多地源自微观,而分工问题则是源自宏观。 Threa...

  • 实现同步的方法

    1.互斥同步 互斥同步(Mutual Exclusion&Synchronization)是常见的一种并发正确性保...

  • Java同步机制之死锁

    Java并发系列番外篇——同步机制(三) 姊妹篇《Java同步机制之synchronized》姊妹篇《Java同步...

网友评论

    本文标题:java并发之互斥和同步

    本文链接:https://www.haomeiwen.com/subject/ummsmttx.html