# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {...} 代码段内。
# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {...} 代码段内唤醒A。
# 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
# 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
# obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。
wait()/sleep()的区别
前面讲了wait/notify机制,Thread还有一个sleep()静态方法,它也能使线程暂停一段时间。sleep与wait的不同点是:sleep并不释放锁,并且sleep的暂停和wait暂停是不一样的。obj.wait会使线程进入obj对象的等待集合中并等待唤醒。
但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException。
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException。
分享到:
相关推荐
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
实际上在web开发中大多数逻辑都是在单个线程中展开的,一个请求都会在一个单独的线程中处理,其中的大部分变量都是属于这个线程的,根本没有必要考虑锁 定,当然对于ASP.NET中的Application对象中的数据,我们就要...
对于一个高性能服务器在处理多数读取,少量写入的场景时,如果还是使用常规的互斥锁方式,显然就不...写完释放锁,所有读取线程又并发读取,详细内容请见:https://blog.csdn.net/u013420701/article/details/79912242
泛型单例父类(带锁线程可释放),很好用的一个泛型单例父类,想将一个类变成单例类的时候,只有继承这个...而且带线程锁,不怕多线程的时候出现错误了,而且还能手动释放;完全成品.cs文件,直接扔项目里就能用;好用的不得了;
锁的持有线程在其获得锁之后和释放锁之前这段时间内所执行的代码被称为临界区。因此,共享数据只允许在临界区内进行访问,临界区一次只能被一个线程执行。 这种同一时刻只能被一个线程持有的锁被称为排他锁或者互斥...
* 继承Thread:线程代码存放Thread子类run方法中 实现 * Runnable:线程代码存放接口的子类的run方法 * wait释放资源,释放锁 * sleep释放资源,不释放锁 */ @SuppressWarnings("all") public class Thread1 { ...
(1)在访问该资源前,首先申请该互斥锁,如果该互斥处于开锁状态,则申请到该锁对象,并立即占有该锁(使该锁处于锁定状态),以防止其它线程访问该资源;如果该互斥锁处于锁定状态,默认阻塞等待; (2)只有锁定...
但如果你在代码里使用这些函数,则往往会遇到各种问题(比如SuspendThread时正好在CRT分配内存的锁中造成其他线程也跟着锁死,TerminateThread时资源未释放)等。 本人经过试验和总结,整理出可以安全的进行暂停、...
4. main 中加flag = 5 将flg在while中-- 这时,主线程输出5次后试图销毁锁,但子线程未将锁释放,无法完成。 5. main 中加pthread_cancel()将子线程取消。 【pthrd_mutex.c】 结论: 在访问共享资源前...
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
1、单线程加锁读写全局数据,每秒读多少次?建议使用读XXX万次,用多少时间来计算。 2、多线程加锁读写全局...3、每个线程每秒只读500次并且读后不要立即释放锁的情况下(执行一段for循环代码),执行2与2.1两个步骤
首先一个线程成功获得一个条件变量后,调用此条件变量的wait()方法会导致这个线程释放这个锁,并进入“blocked”状态,直到另一个线程调用同一个条件变量的notify()方法来唤醒那个进入“blocked”状态的线程。...
当一个线程获得了一个互斥锁并开始访问某个资源时,其他尝试获取该锁的线程将被阻塞,直到原持有锁的线程释放该锁。 2. **信号量(Semaphores)**:信号量是一种更通用的同步机制,它可以用于控制多个线程对共享资源...
生产者消费者详解wait():执行该方法的线程对象,释放同步锁,JVM会把该线程放到等待池中,等待其他线程唤醒该线程 notify():执行该方法的线程唤醒在等待池中等待的任意一个线程,把线程转到锁池中等待(注意锁池和...
首先,在小程序的start()方法中构造了一个名为circleThread的线程并调用线程类的start()方法来启动这一线程,即在小程序的主线程中又开始了一个线程:circleThread。下面的语句建立了一个新的线程: circlethread =...
线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局...当一个线程执行到 pthread_mutex_lock处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁。
资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源的争用,甚至导致死锁 也可能导致读写混乱 ...调用了n次acquire锁请求,则必须调用n次的release才能在线程中释放锁对象 例如: 无锁:
使用场景为一个线程写一个线程读完全不需要锁。可以设定buffer的初始块及数量,初始块是固定大小的,当需要扩环时会动态创建块即不像其它的库块满了就写失败了,当释放时会将动态创建的块还给系统,初始块还给自己的...
//释放所获取的锁2) 然后还需要定义一个读写锁的接口,这个接口的作用就是定义读写锁的特性//获取当前有多少线程正在执行写操作int getWritingWri