解决方案 »
- 高公求高手写一个程序,急急急!
- 难道我要抛弃rmi?
- Java怎么解压带固定密码的ZIP文件(急用,给高分)
- 这样的正则表达式怎么写?!!在线给分
- 怎样按字符为单位一个一个从服务器端接收过来啊?
- 急需Visual age for java 3.5 1000分相谢
- 新手连接数据库的问题
- 初学第一个程序遇到问题了??救急呀!!!!在线等消息
- 基本上没有编程基础的人--唉,都不知道该怎么提问
- jsp中用jsp:useBean生出来的对象可控制在page,session,application,那我new 出来的bean,存活域是什么?
- JSplitPane中setonetouchexpandable方法的实现机制
- 如何对一个方法的执行时间进行超时控制?
所以从你的程序来看,应该是
runname.notifyAll();
改成runname.notifyAll();后也还是不行
注释掉,你运行程序看看,与notifyAll();对比。
主要是你写的逻辑有点乱啊,你用notifyAll()去唤醒别人的时候,别人只能是同一个锁下的wait(),所以你这种思路不太行啊。
你看看这个http://hi.baidu.com/dapplehou/blog/item/14e62834ebe1bc235ab5f504.html。
抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。 notifyAll抛出的原因
IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。第一,不是同一个锁对象的时候,会抛出来
第二,当锁对象之前没有wait的线程的时候,也会抛出来
static ArrayList<String> namelist=new ArrayList<String>();
static String runname="";
public String name;
public int printcount=0;
static int waitcount=0;
public String GetName()
{
return name;
}
public SequenchThread(String name)
{
this.name=name;
namelist.add(name);
synchronized(runname){
if (runname.equals(""))
runname=name;
}
}
public void run()
{
while(true)
{
synchronized(runname)
{
System.out.println("thread"+name+"is running");
if(runname.equals(GetName())){
System.out.println("打印"+GetName());
int j=0;
while(!namelist.get(j).equals(runname))
{
j++;
}
j++;
if(j==namelist.size())
j=0;
runname=namelist.get(j);
printcount++;
if(waitcount>0)
{
runname.notifyAll();
System.out.println("唤醒所有线程");
waitcount=0;
}
}else{
try{
System.out.println("thread"+name+"is wait");
waitcount++;
runname.wait();
System.out.println("thread"+name+" is awake");
}catch(InterruptedException e)
{}
}
}
/* try{
sleep(3000);
}catch(InterruptedException e2)
{}*/
if(printcount==10)
break;
System.out.println("the name of the thread for the next running is "+runname);
}
}public static void main(String args[])
{
new SequenchThread("A").start();
new SequenchThread("B").start();
new SequenchThread("C").start();
}}
运行结果如下:
threadAis running
打印A
the name of the thread for the next running is B
threadAis running
threadAis wait 等待
threadBis running
打印B
threadCis running
打印C
Exception in thread "Thread-2" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at test.SequenchThread.run(SequenchThread.java:45)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at test.SequenchThread.run(SequenchThread.java:45)我现在想问西,为什么在线程A等待的时候调用,线程C调用notifyAll会出错。
每次给runname赋值,那么这个runname的具体对象都会改变
所以虽然synchronized(runname)中用runname做锁,但是三个线程的锁都不同,所以报异常
这个结果应该满意了吧?
public static ArrayList<String> namelist=new ArrayList<String>();
public static String runname="";
public static String runname2="str";//修改public String name;
public int printcount=0;
static int waitcount=0;
public String GetName()
{
return name;
}
public SequenchThread(String name)
{
this.name=name;
namelist.add(name);
synchronized(runname2){
if (runname.equals(""))
runname=name;
}
}
public void run()
{
while(true)
{
synchronized(runname2) //修改 {
System.out.println("thread "+name+" is running");
if(runname.equals(GetName())){
System.out.println("打印"+GetName());
int j=0;
while(!namelist.get(j).equals(runname))
{
j++;
}
j++;
if(j==namelist.size())
j=0;
runname=namelist.get(j);
printcount++;
if(waitcount>0)
{
runname2.notifyAll(); //修改 System.out.println("唤醒所有线程");
waitcount=0;
}
}else{
try{
System.out.println("thread"+name+"is wait");
waitcount++;
runname2.wait(); //修改 System.out.println("thread"+name+" is awake");
}catch(InterruptedException e)
{}
}
}
/* try{
sleep(3000);
}catch(InterruptedException e2)
{}*/
if(printcount==10)
break;
System.out.println("the name of the thread for the next running is "+runname);
}
}public static void main(String args[])
{
new SequenchThread("A").start();
new SequenchThread("B").start();
new SequenchThread("C").start();
}}