Java:从线程处理非静态变量?

时间:2015-02-13 05:26:28

标签: java string multithreading variables static

我的代码的相关摘要是:

public class A {
    String aString;

    public static void main(String[] args) {
        B b = new B();
        new Thread(b).start();
    }
    public static class B implements Runnable {
        public void run() {
            aString = "foo";
        }
    }
}

我有几个月的Java编码经验,但threaddynamicstatic对我来说还是比较新的。为了使线程正确执行,B类必须是静态的,否则只执行线程,而不是两者。我的目标是显然让线程在后台执行,这样我在A类中可能拥有的其他代码可以同时执行。问题是,如果B类是静态的,我就不能操纵字符串aString,因为我得到异常non-static variable aString cannot be referenced from a static context

我已经查询了相关信息,但我没有发现任何与线程中修复此问题有关的内容。我的问题是,如何操作B类中的aString并仍然使线程正常工作(两个类都在运行,而不仅仅是B类)?

3 个答案:

答案 0 :(得分:2)

为了让你的例子有用,你需要这样的东西:

public class A {
    volatile String aString;

    public static void main(String[] args) throws InterruptedException {
        A a = new A();
        Thread t = new Thread(a.new B());
        t.start();
        t.join(); // wait for t to finish
        System.out.println(a.aString); // prints "foo"
    }

    class B implements Runnable {
        public void run() {
            aString = "foo";
        }
    }
}

解决static问题很容易 - 请参阅代码。

我希望其余的代码可以帮助说明在使用线程时需要满足的一些问题。

答案 1 :(得分:0)

B是静态的,所以只存在于类级别,因此不能看到其父类的实例变量

public class A {
    String aString;  // <== instance variable

    public static void main(String[] args) {
        B b = new B();
        new Thread(b).start();
    }
    public static class B implements Runnable {  // <== static class
        public void run() {
            aString = "foo";
        }
    }
}

可能的解决方法。使aString也是静态的

public class A {
    static String aString;

可能的解决方法。使B非静态。这是有点奇怪的地方。 B现在只存在于A的实例级别,因此您需要先创建一个A实例。

public class A {
    String aString;

    public static void main(String[] args) {
        B b = new A().new B();  // <== need to create an A before a B
        new Thread(b).start();
    }
    public class B implements Runnable {
        public void run() {
            aString = "foo";
        }
    }
}

答案 2 :(得分:0)

您要求B类的对象实例(使用new B()创建)来访问您尚未创建的对象实例的成员变量。在您的代码中,没有创建B类的对象。

我认为您可能认为在A类中运行main()方法以某种方式实例化A类的实例 - 事实并非如此。

以下内容将起作用,因为您正在创建A的实例并使其可用于您的B实例。

public class A {
    String aString;

    public static void main(String[] args) {
        A a = new A();
        B b = new B(a);
        new Thread(b).start();
    }
    public static class B implements Runnable {
        private final A a;

        public B(A a){
          this.a = a;
        }

        public void run() {
            a.aString = "foo";
        }
    }
}