java多线程的wait()和notify问题

JamOfCode 2010-05-20 09:46:08
问个问题,我通过synchronized(syncqURL) 控制一些线程的同步,其中syncqURL是个object对象


synchronized(syncqURL)
{
et=s_qURL.poll();
if(et==null)
{
System.out.println(thread.getId()+"is on requiring URL failed");
thread.SetIdle();
if(DownloadThread.AskForIdle())
{
DownloadThread.InterruptAll();
}
else
{
syncqURL.wait();
continue;
}
}
}


这里面有线程被挂起,那么如果我在某处有线程进入


synchronized(syncqURL)
{
s_qURL.add(et);
DownloadThread.NotifyAll();
syncqURL.notifyAll();
}



之前被挂起的线程的执行顺序是wait()语句后,还是重新进入run函数???
...全文
90 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
mochibing 2010-05-20
  • 打赏
  • 举报
回复
看了你的代码,为什么要用静态函数啊?有什么理由吗?
JamOfCode 2010-05-20
  • 打赏
  • 举报
回复
把代码都贴出来大家帮我看看吧。。。。。

实现功能,下载网页,获取网页URL和title

设计的思想:创建N个线程,创建一个储存已下载网页的URL和title还有网页深度的 map,创建一个等待下载的链接的 queue,然后所有线程执行的动作都是在队列头取出url 然后下载,获取title,获取当前网页内的所有链接,添加进queue,再把当前网页添加到map中,防止重复下载

问题: 1.有时候不能结束,有些线程一直活跃,但是当前队列已经没有东西了,不能退出
2.有时候只有一个线程在跑,不知道其他在干嘛。。。。。。。是不是设计有问题?


public static void RunDownloadThread(DownloadThread thread) throws InterruptedException//run函数里面的类静态函数
{
while(!DownloadThread.GetisQuit())
{
System.out.println(thread.getId()+"is on requiring URL");
ElementType et;
synchronized(syncqURL)
{
et=s_qURL.poll();
if(et==null)
{
System.out.println(thread.getId()+"is on requiring URL failed");
thread.SetIdle();
if(DownloadThread.AskForIdle())
{
DownloadThread.InterruptAll();
}
else
{
syncqURL.wait();
continue;
}
}
}

if(et!=null)
{
System.out.println(thread.getId()+"is on requiring URL succeed");
synchronized(syncMap)
{
if(s_map.containsKey(et.url)==false)
{
s_map.put(et.url,et);
}
else
{
continue;
}
}
DownLoadPage(et);
System.out.println(et.url+" "+et.title+" "+et.deep+"线程ID"+thread.getId());
}
}
}


private static boolean DownLoadPage(ElementType et)
{
try
{
System.out.println(Thread.currentThread().getId()+"is on downloading page");
URL url=new URL(et.url);
URLConnection connection=url.openConnection();
connection.connect();
Scanner scanner=new Scanner(connection.getInputStream());
StringBuffer str=new StringBuffer();

System.out.println(Thread.currentThread().getId()+"is on save String");
for(;scanner.hasNextLine();)
{
str.append(scanner.nextLine());
str.append("\n");
}

//需要统一编码
et.title=FindTitle(str);
if(et.deep<1)
{
AnalyzeStream(str,et.deep);
}
return true;
}
catch(IOException ex)
{
}
return false;
}


private static void AnalyzeStream(StringBuffer str,int deep)
{
System.out.println(Thread.currentThread().getId()+"is on analyzing String");
for(int curPos=str.indexOf(s_matchLink,0);curPos!=-1;curPos=str.indexOf(s_matchLink,curPos))
{
String temp=new String();
curPos+=s_matchLink.length();
int endPos=str.indexOf("\"", curPos);
temp=str.substring(curPos, endPos);
if(temp.indexOf("http")!=-1&&temp.indexOf("qq")!=-1)
{
ElementType et=new ElementType();
et.url=temp;
et.deep=deep+1;
synchronized(syncqURL)
{
s_qURL.add(et);
DownloadThread.NotifyAll();
syncqURL.notifyAll();
}
}
}
}


高手帮忙看看吧。。。是不是我理解多线程有误???哪里写错了~~~~~
无聊司马 2010-05-20
  • 打赏
  • 举报
回复
看不太懂
Mybeautiful 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 jamofcode 的回复:]
问个问题,我通过synchronized(syncqURL) 控制一些线程的同步,其中syncqURL是个object对象

Java code

synchronized(syncqURL)
{
et=s_qURL.poll();
if(et==null)
{
……
[/Quote]

是 syncqURL.wait();的语句, 所谓 wait就是等下而已。



如果楼主是要个不结束的run方法。
建议写成
public void run(){
while(true){
//你的逻辑。
}
}
奋斗并快乐着 2010-05-20
  • 打赏
  • 举报
回复
DownloadThread.NotifyAll(); 这句用不着

notify之后会从wait之后的语句继续执行

wait控制比较麻烦,占开销也不低,如果对实时性要求不是很高,可以简单加个标志:
public bool bNotified = false;
//...
else
{
bNotified = false;
while(!bNotified){
try{
Thread.sleep(1000);
}catch(ThreadInterruptedException e){
break;
}
}
}

62,614

社区成员

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

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