关于多线程的一点疑问

bsk 2003-01-20 11:59:21
正在看《Java程序设计教程 下册 高级篇》,第15章就专门讲多线程。看完了后,有一点问题还找不到答案。疑问如下:
假如有3个线程thread1、thread2、thread3,其中thread1和thread2由于某种原因处于wait状态,现在想在thread3中只想notify thread1,怎样指定只通知thread1而不通知thread2?不知那位高手能帮我解答一下?
还有,该章最后一个例子Fig.15-7:RandomCharacter.java执行后,假如同时Suspended两个线程(比如是Thread1和Thread2),再启动Thread1,有时候可以启动,有时候不行,不知是什么原因?我怀疑是没有指定具体要通知哪个线程有关系。
谁可以帮我一下呀?先谢谢啦,分肯定不会少给的啦!
...全文
67 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
bsk 2003-01-22
  • 打赏
  • 举报
回复
结贴啦!

感谢helpall() 的大力帮助,非常感谢!真的是一被点破有种豁然开朗的感觉

也感谢hayai(生命树) 的热心帮助,感谢各位的支持。谢谢!
helpall 2003-01-22
  • 打赏
  • 举报
回复
Just changed two functions. Try it:
public void run()
{
Thread currentThread = Thread.currentThread();
int index = getIndex( currentThread );
char displayChar;

while ( threads[ index ] == currentThread ) {
// sleep from 0 to 1 second
try {
// Thread.sleep( (int) ( Math.random() * 1000 ) );

if ( suspended[ index ] &&
threads[ index ] == currentThread ){
System.out.println((index==0?" ":
index==1?" ":
" ")+"zzzzzzzz");
synchronized(currentThread) {
currentThread.wait();
}
System.out.println((index==0?" ":
index==1?" ":
" ")+"--------");
}
}
catch ( InterruptedException e ) {
// System.err.println( "sleep interrupted" );
System.out.println((index==0?" ":
index==1?" ":
" ")+"++++++++++");
}

displayChar = alphabet.charAt(
(int) ( Math.random() * 26 ) );
outputs[ index ].setText( currentThread.getName() +
": " + displayChar );
}

System.err.println(
currentThread.getName() + " terminating" );
}

public void actionPerformed( ActionEvent e )
{
for ( int i = 0; i < checkboxes.length; i++ ) {
if ( e.getSource() != checkboxes[ i ] )
continue;
suspended[ i ] = ((JCheckBox)e.getSource()).isSelected();
outputs[ i ].setBackground(suspended[ i ] ? Color.red : Color.green );

if ( suspended[ i ] )
return;
synchronized(threads[i]) {
threads[i].notify();
}
return;
}
}
colors 2003-01-21
  • 打赏
  • 举报
回复
呵呵!
写代码的人很多啊
bsk 2003-01-21
  • 打赏
  • 举报
回复
谁能帮我把RandomCharacter.java编译一下,找到那个bug的解决方法呀?
helpall 2003-01-20
  • 打赏
  • 举报
回复
// thread1
sig1.wait();
// thread2
sig2.wait();
// thread3
sig1.notify();
================or =============
class sigStruct {
String name;
}
// thread1
do { try{
sig.wait();
}catch(Exception e){}
while(!sig.name.equals("thread1"));

// thread2
do { try{
sig.wait();
}catch(Exception e){}
while(!sig.name.equals("thread2"));

// thread3
sig.name="thread1";
sig.notify();

没有该书,另外的问题不能回答.
helpall 2003-01-20
  • 打赏
  • 举报
回复
你需要把notify()或notifyAll()放在synchronized(Object)中执行. 例:

synchronized(sig) {
sig.notify();
}
hayai 2003-01-20
  • 打赏
  • 举报
回复
I guess u guys have misunderstood how Thread waiting works.
The key is the term "monitor".
When a thread is waiting, it's waiting on a monitor.
A monitor is an Object which the "synchronized" keyword is used on.
notify() method(s) will wake up the thread or threads which has/have been put to wait or sleep.
Notice here: notify is called through the Monitor, not the thread.
The difference between notify and notifyAll is one wakes one thread randomly, the other wakes all up.
If an Object is not a "monitor" but the notify method is called, the IllegalMonitorStateException will be thrown.
For more information, email me at pao22pao@hotmail.com
bsk 2003-01-20
  • 打赏
  • 举报
回复
测试的RandomCharacters.html文件如下:

<html>
<applet code="RandomCharacters.class" width=275 height=90>
</applet>
</html>
bsk 2003-01-20
  • 打赏
  • 举报
回复
《Java程序设计教程 下册 高级篇》,Fig.15-7:RandomCharacter.java代码如下:

// Fig. 15.7: RandomCharacters.java
// Demonstrating the Runnableinterface
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class RandomCharacters extends JApplet
implements Runnable,
ActionListener {
private String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private JLabel outputs[];
private JCheckBox checkboxes[];
private final static int SIZE = 3;

private Thread threads[];
private boolean suspended[];

public void init()
{
outputs = new JLabel[ SIZE ];
checkboxes = new JCheckBox[ SIZE ];
threads = new Thread[ SIZE ];
suspended = new boolean[ SIZE ];

Container c = getContentPane();
c.setLayout( new GridLayout( SIZE, 2, 5, 5 ) );

for ( int i = 0; i < SIZE; i++ ) {
outputs[ i ] = new JLabel();
outputs[ i ].setBackground( Color.green );
outputs[ i ].setOpaque( true );
c.add( outputs[ i ] );

checkboxes[ i ] = new JCheckBox( "Suspended" );
checkboxes[ i ].addActionListener( this );
c.add( checkboxes[ i ] );
}
}

public void start()
{
// create threads and start every time start is called
for ( int i = 0; i < threads.length; i++ ) {
threads[ i ] =
new Thread( this, "Thread " + (i + 1) );
threads[ i ].start();
}
}

public void run()
{
Thread currentThread = Thread.currentThread();
int index = getIndex( currentThread );
char displayChar;

while ( threads[ index ] == currentThread ) {
// sleep from 0 to 1 second
try {
Thread.sleep( (int) ( Math.random() * 1000 ) );

synchronized( this ) {
while ( suspended[ index ] &&
threads[ index ] == currentThread )
wait();
}
}
catch ( InterruptedException e ) {
System.err.println( "sleep interrupted" );
}

displayChar = alphabet.charAt(
(int) ( Math.random() * 26 ) );
outputs[ index ].setText( currentThread.getName() +
": " + displayChar );
}

System.err.println(
currentThread.getName() + " terminating" );
}

private int getIndex( Thread current )
{
for ( int i = 0; i < threads.length; i++ )
if ( current == threads[ i ] )
return i;

return -1;
}

public synchronized void stop()
{
// stop threads every time stop is called
// as the user browses another Web page
for ( int i = 0; i < threads.length; i++ )
threads[ i ] = null;

notifyAll();
}

public synchronized void actionPerformed( ActionEvent e )
{
for ( int i = 0; i < checkboxes.length; i++ ) {
if ( e.getSource() == checkboxes[ i ] ) {
suspended[ i ] = !suspended[ i ];

outputs[ i ].setBackground(
!suspended[ i ] ? Color.green : Color.red );

if ( !suspended[ i ] )
notify();

return;
}
}
}
}

/**************************************************************************
* (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall. *
* All Rights Reserved. *
* *
* DISCLAIMER: The authors and publisher of this book have used their *
* best efforts in preparing the book. These efforts include the *
* development, research, and testing of the theories and programs *
* to determine their effectiveness. The authors and publisher make *
* no warranty of any kind, expressed or implied, with regard to these *
* programs or to the documentation contained in these books. The authors *
* and publisher shall not be liable in any event for incidental or *
* consequential damages in connection with, or arising out of, the *
* furnishing, performance, or use of these programs. *
*************************************************************************/
希偌 2003-01-20
  • 打赏
  • 举报
回复
楼上已经关注很多帖子了,就不能说两句吗???
bsk 2003-01-20
  • 打赏
  • 举报
回复
To helpall():
我用了thread1.notify(),但运行的时候出现错误,提示:
Exception occurred during event dispatching:
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.notify(Native Method)
at RandomCharacters.actionPerformed(RandomCharacters.java:111)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:14
45)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Abstra
ctButton.java:1499)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel
.java:373)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.
java:263)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonL
istener.java:211)
at java.awt.Component.processMouseEvent(Component.java:3710)
at java.awt.Component.processEvent(Component.java:3539)
at java.awt.Container.processEvent(Container.java:1159)
at java.awt.Component.dispatchEventImpl(Component.java:2588)
at java.awt.Container.dispatchEventImpl(Container.java:1208)
at java.awt.Component.dispatchEvent(Component.java:2492)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:2451
)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:2216)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:2125)
at java.awt.Container.dispatchEventImpl(Container.java:1195)
at java.awt.Component.dispatchEvent(Component.java:2492)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:334)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:126)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:93)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:88)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:80)
Billy_Chen28 2003-01-20
  • 打赏
  • 举报
回复
关注!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧