Java Thread使用静态或非静态嵌套类

时间:2009-09-07 06:41:46

标签: java static multithreading non-static

我遇到了一个非常奇怪的问题。   我的程序看起来像这样:

class Outter{

      class Inner extends Thread {
           public void run(){
               // do something
           }
      }

      public void func() {
           new Inner().start();
           // Thread.sleep() for a while to see if the above thread has finished
           // if not stop the thread
  }

问题是Inner类似乎永远不会真正运行。因此func将始终在它完成它应该做的事情之前停止它。这两个线程应该并发运行,但实际上只有主线程正在运行,另一个线程处于运行状态,但被阻塞。    我尝试将Inner类更改为静态类。这次运作良好。    但我仍然没有理由,希望有人可以帮忙解释一下。

4 个答案:

答案 0 :(得分:4)

您的问题无法复制。

public class Outer {

    class Inner extends Thread {
        public void run() {
            System.out.println("inner");
        }
    }

    public void func() {
        new Inner().start();
        System.out.println("outer");
    }

    public static void main(String... args) {
        new Outer().func();
    }

}

这实际上运行完美并输出“outer”和“inner”。

答案 1 :(得分:0)

我最初的想法是你看到线程调度“意外”。您没有向我们展示您的真实代码,因此很难看出这是否可行。我已经预期会在sleep()中显示注释以防止这种情况,但是我们看不到真正的代码。

然而,另一个想法,你说

  

func将在它完成它应该做的事情之前总是停止它

这看起来很奇怪。我希望使用某种共享状态变量,同步和等待以确保两个线程就发生的事情达成一致。使用那些你不可避免地产生控制,以便两个线程获得时间片。

作为一个实验,我可能会在开始后添加一个Thread.yield()调用,看看是否有任何影响。

答案 2 :(得分:0)

       // Thread.sleep() for a while to see if the above thread has finished
       // if not stop the thread

我的猜测是这个逻辑有一些问题,而你不应该停止线程。当然,如果没有再现问题的例子,就无法分辨。

答案 3 :(得分:0)

我刚刚尝试编写一个简单的代码来显示问题,但我失败了。   似乎这个问题不是关于静态和非staic类,因为如果我不在outter类中使用成员变量,非静态类也可以正常工作。但是一旦我使用它,就会出现问题。   重现问题并非易事。以下代码没有问题。

package test;

public class Tester {

    private String message = "Hello";

    private class Inner extends Thread {

        public void run(){
            try {
                System.out.println(message);
            } catch (Exception e) {
                // TODO: handle exception
            }

        }
    }

    public void func(){
        Inner inner = new Inner();
        inner.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO: handle exception
        }
        System.out.println("stop");
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new Tester().func();
    }

}