java线程中的一些问题
(1)notifyAll无法唤醒的问题
一个线程处于wait状态,另一个线程无法唤醒它。主要原因不是共享变量的问题,只要共享变量为对象成员或静态变量即可。因为wait()和notifyAll必须属于同一实体,所以当调用了a.wait()后,必须调用a.notifyAll才能唤醒a线程。
(2)java.lang.IllegalMonitorStateException异常
这个异常与前一个问题有一定的关系,解决了上一个问题后,只要在wait和notify前面加上synchronized(Object)或在调用这两个方法的函数中加上synchronized即可解决。
(3)线程对象如果是一个类的成员,可能无法创建,原因是这个类的对象没有创建,或Thread对象被析构
如下面是一个线程类:
package test; public class MyThread implements Runnable { public MyThread() { } public void run() { // TODO Auto-generated method stub while(true) { System.out.println("My Thread are runing"); try { synchronized(this) { this.wait(1000);} } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
如果主类中加入一个该类的成员:
package test; public class testThread { private static MyThread myThread; public testThread() { // TODO Auto-generated constructor stub myThread = new MyThread(); } public static void main(String[] args) { Thread thread = new Thread(myThread); thread.start(); } }
则此时,这个线程无法运行。主要原因是该线程是testThread的成员,而main函数运行时,并没有创建testThread对象,所以myThread并没有被创建。
改为下面的代码即可运行:
package test; public class testThread { private static MyThread myThread; public testThread() { // TODO Auto-generated constructor stub myThread = new MyThread(); } public static void main(String[] args) { // TODO Auto-generated method stub testThread t = new testThread(); Thread thread = new Thread(myThread); thread.start(); } }
但是如下代码还是不能运行,不管myThread是不是静态成员
package test; public class TestThread2 { private MyThread myThread; public TestThread2() { MyThread myThread = new MyThread(); } public static void main(String[] args) { // TODO Auto-generated method stub TestThread2 t = new TestThread2(); t.runThread(); } public void runThread() { Thread thread = new Thread(myThread); thread.start(); } }
但是如果将Thread变量也设置为成员,则可以运行
package test; public class TestThread2 { private MyThread myThread; private Thread thread; public TestThread2() { MyThread myThread = new MyThread(); thread = new Thread(myThread); } public static void main(String[] args) { // TODO Auto-generated method stub TestThread2 t = new TestThread2(); t.runThread(); } public void runThread() { //Thread thread = new Thread(new MyThread()); thread.start(); } }
总结,如果只将runnable作为成员,在创建时由于Thread 变量是临时变量,可能被析构,所以不能创建线程。但如果Thread与runnable都作为成员,则没有问题了。