解决方案 »
- 帮我看一下是什么错误?
- JTextPane 的问题
- 如何把一个带有"年月日"及"时分秒"的字符串,插入到数据类型为DateTime的MS-SQL库中,在线等,解决即刻结帖
- 100分,马上揭贴!!最基本的问题,请别笑话
- 问个关于JBuilder的问题(JBuilder 6)
- 关于在linux下的服务器关机程序?
- 谁能救救我的win2000profesional.谢谢了
- 我在用iplanet application server6.5的“sample applications”出现如下的错误
- 哪里有jbuilder6下载!!!快快
- 前几天介绍java编程书籍的帖子在哪里? 找的好辛苦
- 【在线等】我想看看TreeSet的输出(小问题)
- 如何通过mina创建单服务端+多客户端
import java.util.List;public class NotifySpecifiedThread { /** the thread number of consumer **/
private static final int consumerNumber = 10;
/** the consumer Thread Name prefix **/
private static final String consumerThreadName = "consumer_notify";
/** the consumer thread index that will be notified **/
private static final int index = 5;
/** the list register all the consumer list **/
private static final List<Thread> registeThreads = new ArrayList<Thread>(
consumerNumber); /**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= consumerNumber; i++) {
final Thread t = new ConsumerThread();
t.setName(consumerThreadName + i);
registeThreads.add(t);
} for (final Thread t : registeThreads) {
t.start();
} new ProducerThread().join(); } /**
* Consumer synchronize the current instance itself
*
* @author Administrator
*
*/
static class ConsumerThread extends Thread {
@Override
public void run() {
final Thread t = Thread.currentThread();
final ThreadLocal<Boolean> isWait = new ThreadLocal<Boolean>();
isWait.set(true); synchronized (this) {
while (isWait.get()) {
try {
System.out.println("i am ready to wait,"
+ " the thread name is:" + t.getName());
this.wait();
isWait.set(false);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
} System.out.println("i have been released, the thread name is:"
+ t.getName());
}
} } /**
* the Producer will synchronize consumer instance as thread monitor
*
* @author Administrator
*
*/
static class ProducerThread extends Thread { public ProducerThread() {
this.start();
} @Override
public void run() {
for (Thread consumer : registeThreads) {
final String consumerThreadName = consumer.getName();
if (consumerThreadName.equalsIgnoreCase(consumerThreadName
+ index)) {
synchronized (consumer) {
consumer.notifyAll();
}
} }
} }}
帖子不能修改,郁闷。。package thread;import java.util.ArrayList;
import java.util.List;public class NotifySpecifiedThread { /** the thread number of consumer **/
private static final int consumerNumber = 10;
/** the consumer Thread Name prefix **/
private static final String consumerThreadName = "consumer_notify";
/** the consumer thread index that will be notified **/
private static final int index = 5;
/** the list register all the consumer list **/
private static final List<Thread> registeThreads = new ArrayList<Thread>(
consumerNumber); /**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= consumerNumber; i++) {
final Thread t = new ConsumerThread();
t.setName(consumerThreadName + i);
registeThreads.add(t);
} for (final Thread t : registeThreads) {
t.start();
} new ProducerThread().join(); } /**
* Consumer synchronize the current instance itself
*
* @author Administrator
*
*/
static class ConsumerThread extends Thread {
@Override
public void run() {
final Thread t = Thread.currentThread();
final ThreadLocal<Boolean> isWait = new ThreadLocal<Boolean>();
isWait.set(true); synchronized (this) {
while (isWait.get()) {
try {
System.out.println("i am ready to wait,"
+ " the thread name is:" + t.getName());
this.wait();
isWait.set(false);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
} System.out.println("i have been released, the thread name is:"
+ t.getName());
}
} } /**
* the Producer will synchronize consumer instance as thread monitor
*
* @author Administrator
*
*/
static class ProducerThread extends Thread { public ProducerThread() {
this.start();
} @Override
public void run() {
for (Thread consumer : registeThreads) {
final String name = consumer.getName();
if (name.equalsIgnoreCase(consumerThreadName + index)) {
synchronized (consumer) {
consumer.notifyAll();
}
} }
} }}
1. 这里Consumer为什么要监视自己的变量呢? 且该变量不是共享的。
2. Producer监视Consumer变量,然后notifyAll(),就能唤醒指定的线程。这是啥原因呢?
这段代码其实和你上个帖子2楼回答的一样
可是如果是这样的话,那就起不到共享变量释放时唤醒特定线程的目的了啊!
每个消费者锁住自己进行wait(),然后生产者锁住指定的消费者线程,对该线程唤醒,这样的话,还是达不到开始说的,当共享变量释放时, 能够指定一个消费者进行唤醒的目的。
可能我没弄清楚你的要求,但是它上面给的例子确实是指定线程唤醒啊,他那段代码唯一可能要改的是消费者run里面不应该用isWait.get()当作while的条件,这样做会使消费者执行一次消费后就退出了可能你想像的是 (伪代码)object.release();
object.notify(threadID);但事实是object.release();
Thread.findById(threadID).notify();因为第一种方式的第二行java里是做不到的,当所有线程共享同一把锁时无法唤醒指定线程
所以需要每个线程有自己的锁第二种情况并不影响你在消费者线程里有以下操作比如构造时注入你的共享对象CustomThread(Ojbect object)并在处理这个资源时加同步while(true){
...
this.wait();
sychronized(this.object){
....
}
}
可能我没弄清楚你的要求,但是它上面给的例子确实是指定线程唤醒啊,他那段代码唯一可能要改的是消费者run里面不应该用isWait.get()当作while的条件,这样做会使消费者执行一次消费后就退出了可能你想像的是 (伪代码)object.release();
object.notify(threadID);但事实是object.release();
Thread.findById(threadID).notify();因为第一种方式的第二行java里是做不到的,当所有线程共享同一把锁时无法唤醒指定线程
所以需要每个线程有自己的锁第二种情况并不影响你在消费者线程里有以下操作比如构造时注入你的共享对象CustomThread(Ojbect object)并在处理这个资源时加同步while(true){
...
this.wait();
sychronized(this.object){
....
}
}
明白你的意思,可是我按照这样修改之后的共享变量的代码如下,还是无法顺利唤醒:package slot;
import java.util.ArrayList;
import java.util.List;
public class NotifySpecificThread {
/** the thread number of consumer **/
private static final int consumerNumber = 10;
/** the consumer Thread Name prefix **/
private static final String consumerThreadName = "consumer_notify";
/** the consumer thread index that will be notified **/
private static final int index = 6;
/** the list register all the consumer list **/
private static final List<Thread> registeThreads = new ArrayList<Thread>(
consumerNumber);
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Slot s = new Slot();
for (int i = 1; i <= consumerNumber; i++) {
final Thread t = new ConsumerThread(s);
t.setName(consumerThreadName + i);
registeThreads.add(t);
}
for (final Thread t : registeThreads) {
t.start();
}
new ProducerThread(s).join();
}
/**
* Consumer synchronize the current instance itself
*
* @author Administrator
*
*/
static class ConsumerThread extends Thread {
Slot slot ;
ConsumerThread(Slot s){
slot = s ;
}
@Override
public void run() {
final Thread t = Thread.currentThread();
final ThreadLocal<Boolean> isWait = new ThreadLocal<Boolean>();
isWait.set(true);
synchronized (this) {
while (slot.slotNum==0) {
try {
System.out.println("i am ready to wait,"
+ " the thread name is:" + t.getName());
this.wait();
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}
slot.consume();
System.out.println("i have been released, the thread name is:"
+ t.getName());
}
}
}
/**
* the Producer will synchronize consumer instance as thread monitor
*
* @author Administrator
*
*/
static class ProducerThread extends Thread {
Slot slot ;
public ProducerThread(Slot s) {
this.slot = s;
this.start();
}
@Override
public void run() {
for (Thread consumer : registeThreads) {
final String name = consumer.getName();
if (name.equalsIgnoreCase(consumerThreadName + index)) {
synchronized (consumer) {
consumer.notifyAll();
}
}
}
}
}
}class Slot {
public int slotNum = 0; public synchronized void produce() {
slotNum++;
} public synchronized void consume() {
slotNum--;
}
}
这是什么原因呢?
可能我没弄清楚你的要求,但是它上面给的例子确实是指定线程唤醒啊,他那段代码唯一可能要改的是消费者run里面不应该用isWait.get()当作while的条件,这样做会使消费者执行一次消费后就退出了可能你想像的是 (伪代码)object.release();
object.notify(threadID);但事实是object.release();
Thread.findById(threadID).notify();因为第一种方式的第二行java里是做不到的,当所有线程共享同一把锁时无法唤醒指定线程
所以需要每个线程有自己的锁第二种情况并不影响你在消费者线程里有以下操作比如构造时注入你的共享对象CustomThread(Ojbect object)并在处理这个资源时加同步while(true){
...
this.wait();
sychronized(this.object){
....
}
}晕,刚才没仔细看结果,重新修改了下代码,发现6确实被唤醒了,只不过刚被唤醒又陷入wait(),看来这样确实是能对特定线程实现唤醒的!
代码如下:package slot;
import java.util.ArrayList;
import java.util.List;
public class NotifySpecificThread {
/** the thread number of consumer **/
private static final int consumerNumber = 10;
/** the consumer Thread Name prefix **/
private static final String consumerThreadName = "consumer_notify";
/** the consumer thread index that will be notified **/
private static final int index = 6;
/** the list register all the consumer list **/
private static final List<Thread> registeThreads = new ArrayList<Thread>(
consumerNumber);
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Slot s = new Slot();
for (int i = 1; i <= consumerNumber; i++) {
final Thread t = new ConsumerThread(s);
t.setName(consumerThreadName + i);
registeThreads.add(t);
}
for (final Thread t : registeThreads) {
t.start();
}
new ProducerThread(s).join();
}
/**
* Consumer synchronize the current instance itself
*
* @author Administrator
*
*/
static class ConsumerThread extends Thread {
Slot slot ;
ConsumerThread(Slot s){
slot = s ;
}
@Override
public void run() {
final Thread t = Thread.currentThread();
synchronized (this) {
while (slot.slotNum==0) {
try {
System.out.println("i am ready to wait,"
+ " the thread name is:" + t.getName());
this.wait();
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}
slot.consume();
System.out.println("i have been released, the thread name is:"
+ t.getName());
}
}
}
/**
* the Producer will synchronize consumer instance as thread monitor
*
* @author Administrator
*
*/
static class ProducerThread extends Thread {
Slot slot ;
public ProducerThread(Slot s) {
this.slot = s;
this.start();
}
@Override
public void run() {
for (Thread consumer : registeThreads) {
final String name = consumer.getName();
if (name.equalsIgnoreCase(consumerThreadName + index)) {
synchronized (consumer) {
consumer.notifyAll();
}
}
}
}
}
}class Slot {
public int slotNum = 0; public synchronized void produce() {
slotNum++;
} public synchronized void consume() {
slotNum--;
}
}
i am ready to wait, the thread name is:consumer_notify4
i am ready to wait, the thread name is:consumer_notify6
i am ready to wait, the thread name is:consumer_notify2
i am ready to wait, the thread name is:consumer_notify3
i am ready to wait, the thread name is:consumer_notify5
i am ready to wait, the thread name is:consumer_notify7
i am ready to wait, the thread name is:consumer_notify8
i am ready to wait, the thread name is:consumer_notify9
i am ready to wait, the thread name is:consumer_notify10
i am ready to wait, the thread name is:consumer_notify6可见6确实是被精确唤醒了的! 谢谢诸位大神了!
可能我没弄清楚你的要求,但是它上面给的例子确实是指定线程唤醒啊,他那段代码唯一可能要改的是消费者run里面不应该用isWait.get()当作while的条件,这样做会使消费者执行一次消费后就退出了可能你想像的是 (伪代码)object.release();
object.notify(threadID);但事实是object.release();
Thread.findById(threadID).notify();因为第一种方式的第二行java里是做不到的,当所有线程共享同一把锁时无法唤醒指定线程
所以需要每个线程有自己的锁第二种情况并不影响你在消费者线程里有以下操作比如构造时注入你的共享对象CustomThread(Ojbect object)并在处理这个资源时加同步while(true){
...
this.wait();
sychronized(this.object){
....
}
} 可是这里还有个疑问,为什么可以像这种方式唤醒特定线程呢:
Producer:
synchronized (consumerThread) {
consumer.notifyAll();
}
这样就能唤醒一个特定线程。 就拿上面楼里的程序来说, consumerThread在wait()后,应该是放弃了锁并在slot的一个公共区域内等待被唤醒,此时Producer锁住该线程,并执行notifyAll()操作,为什么就能唤醒呢? slot的锁怎么办呢?