package thread;
import java.util.PriorityQueue;
import java.util.Random;
/**
* Java在多线程环境下,在那些情况下会释放线程所持锁,那些不会?
* 一个等待线程只有获取锁时,才会恢复运行。当持有锁的线程不在需要锁时应及时释放该锁这一点很重要避免其他线程过长等待。
* 释放锁的条件:
* 1.当执行完同步代码块,就会释放锁。(synchronize)
* 2.当在同步代码中执行了锁对象的wait()时,当前线程就会释放锁,被放入到锁对象的等待池中。(等待其他线程调用锁对象notify(),从线程池任意提取一线程去竞争锁来恢复执行)
* 3.当在执行同步代码块过程中,遇到异常而使线程终止,锁被释放。(exception)
* 不释放锁的条件:
* 1.在执行同步代码块过程中,调用了Thread的sleep(),当前线程放弃CPU开始睡眠,但是在睡眠过程中并不会释放锁
* 2.在执行同步代码块过程中,调用了Thread的yield(),当前线程放弃CPU但不会释放锁。
* 3.在执行同步代码块的过程中,其他线程执行了当前线程对象的suspend()方法,当前线程被暂停,但不会释放锁。
*/
public class ThreadTest7 {
private int pq_size = 10;
private PriorityQueue<Integer> pq = new PriorityQueue<Integer>(pq_size);
public static void main(String[] args) {
ThreadTest7 test= new ThreadTest7();
test.new Consumer().start();
new Thread(test.new Procedure()).start();
}
//消费者线程
public class Consumer extends Thread{
public void run(){
while (true) {
synchronized (pq) {
System.out.println("################消费者获取了pq对象的锁################");
while(pq.size()==0){//如果队列为空,消费线程需要释放pq对象的锁,被放入到pq对象的等待池中等待pq对象调用notify方法
try {
System.out.println("队列已空,请生产者进行操作......");
Thread.sleep(6000);
pq.wait();//线程被挂起,释放线程持有的锁
System.out.println("************其他线程调用了bq对象的notify()方法,使线程["+Thread.currentThread().getName()+"]获得bq对象的锁,重新开始从这里执行************");
} catch (InterruptedException e) {
e.printStackTrace();
pq.notify();
}
}
pq.poll();//从队列中取出一个元素
System.out.println("Consumer----------->从队列中取出一个元素,队列现有元素["+pq.size()+"]个");
try {
Thread.sleep(6000);//
} catch (InterruptedException e) {
e.printStackTrace();
pq.notify();
}finally{
pq.notify();
}
System.out.println("同步代码块执行完毕,["+Thread.currentThread().getName()+"]线程释放bq对象的锁");
}
}
}
}
//生产者线程
public class Procedure implements Runnable{
@Override
public void run() {
while (true) {
synchronized (pq) {
System.out.println("################生产者获取了pq对象的锁################");
while (pq.size()==10) {//队列已满,生产者线程需要释放pq对象的锁,被放入到pq对象的等待池中。同时要从pq对象的等待池中释放一个消费者线程去竞争pq对象的锁
try {
System.out.println("队列已空,请消费者进行操作......");
Thread.sleep(6000);
pq.wait();
System.out.println("************其他线程调用了bq对象的notify()方法,使线程["+Thread.currentThread().getName()+"]获得bq对象的锁,重新开始从这里执行************");
} catch (InterruptedException e) {
e.printStackTrace();
pq.notify();
}
}
pq.offer(new Random().nextInt(100));//向队列中添加一个元素
System.out.println("Procedure----------->向队列中添加一个元素,队列中现有元素["+pq.size()+"]个");
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
pq.notify();
}
System.out.println("同步代码块执行完毕,["+Thread.currentThread().getName()+"]线程释放bq对象的锁");
}
}
}
}
}
- 浏览: 12219 次
- 性别:
- 来自: 杭州
相关推荐
在 Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信。。举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内容待...
使用Java多线程的wait和notify方法实现最简单的生产者消费者模式
Java 同步方式 wait和notify/notifyall
主要介绍了Java 中Object的wait() notify() notifyAll()方法使用的相关资料,需要的朋友可以参考下
wait()、notify()和notifyAll()方法2---马克-to-win java视频
wait()、notify()和notifyAll()方法1---马克-to-win java视频
java代码-wait-notify 生产者消费者
wait和notify讲解
使用wait()和notify()实现的生产者与消费者模型,可以了解如何使用wait()和notify()进行线程间通信。(上一次上传的代码有一个问题没有考虑到,这次修补了——CSDN没法撤销资源,只能再上传了)
主要介绍了Object类wait及notify方法原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
//下面的消费者类对象和生产者类对象所操作的是同一个同步堆栈对象 Producer p1 = new Producer(stack,ce); new Thread(p1).start();//生产者线程启动 Consumer c1 = new Consumer(stack,ce); new Thread(c1)....
java中多线程编程notify、wait的使用
Java多线程的样例代码,工程,内含wait()、notify()和sychronized的使用范例。
java多线程下wait和notify的作用
源码—Java多线程5—死锁和wait notify notifyAll
java多线程之wait,notify的用法([ 详解+实例 ]).
java-wait和notify的用法.pdf
开一个子线程来完成一个循环处理的工作,我在主线程中能灵活控制这个子线程的开始、暂停/继续、结束。