zoukankan      html  css  js  c++  java
  • 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都作为成员,则没有问题了。

  • 相关阅读:
    jQuery Validate 表单验证
    在同一个页面使用多个不同的jQuery版本,让它们并存而不冲突
    移动端手势库hammerJS 2.0.4官方文档翻译
    Linux下查看nginx安装目录
    Mac Mini中添加VNC访问
    CSS3属性选择通配符
    【LeetCode】9 Palindrome Number 回文数判定
    【LeetCode】8. String to Integer (atoi) 字符串转整数
    【LeetCode】7. Reverse Integer 整型数反转
    【LeetCode】6. ZigZag Conversion 锯齿形转换
  • 原文地址:https://www.cnblogs.com/myboat/p/12986932.html
Copyright © 2011-2022 走看看