• 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都作为成员,则没有问题了。

  • 相关阅读:
    获取windows所有用户名
    windbg内存查看(d*)
    Windbg查看调用堆栈(k*)
    Windbg调试互斥体(Mutex)死锁
    Windbg调试关键区(CriticalSection)死锁
    "R6002 floating point support not loaded"错误
    由可变参数引起的崩溃
    【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现
    jdk1.8源码解析(1):HashMap源码解析
    Java annotation浅析
  • 原文地址:https://www.cnblogs.com/myboat/p/12986932.html
Copyright © 2020-2023  润新知