从Runnable类中访问共享变量

时间:2011-08-22 12:44:06

标签: java multithreading shared-memory

我需要在Main类的main()方法中定义一个共享变量。我需要两个线程才能访问该共享变量。我通过实现Runnable接口并实现接口的抽象run()方法来创建线程。如何在我的类中定义的实现Runnable接口的run()方法中引用Main类的main()方法中定义的共享变量?显然只是通过名字调用它们是行不通的 - 因为它们出现在我的Runnable类的范围之外。

编辑 - 道歉,这是一个简单的例子

public Class DoThread implements Runnable {

    public void run(){
        sharedVar += 1
    }


}

并在单独的.class文件中:

public Class Main {

    public static void main(String[] args) {
        int sharedVar = 0;

        Thread t1 = new Thread(new DoThread());
        Thread t2 = new Thread(new DoThread());

        t1.start();
        t2.start();

        t1.join();
        t2.join();

    }


}

所以我应该创建一个对象来存储共享var,然后在创建线程时将该对象传递给两个DoThread()构造函数?有时在java通过ref或传递var之间会感到困惑,所以如果我这样做,t2会看到t1对共享var的改变吗?

4 个答案:

答案 0 :(得分:11)

好吧,如果你声明一个 local 变量,除了在该方法中创建的类之外,你将无法引用它。

您在哪里实施Runnable?如果它在同一个类中,那么你可以使它成为一个实例变量,并使main在你创建线程的同一个实例上设置变量,或者使它成为一个静态变量。如果Runnable是在另一个类中实现的,那么当你构造一个该类的实例时,你可以给它所需的数据 - 目前还不清楚这意味着什么...正如其他人所说的那样,代码会有用的。 (例如,线程是否需要能够在原始数据中看到更改?)

顺便说一下,线程相对较高,而在类之间传播数据是相对基础的。如果您是Java新手,我建议您开始使用比线程更简单的方法。

编辑:对于您的示例,您应该使用AtomicInteger,如下所示:

import java.util.concurrent.atomic.AtomicInteger;

class DoThread implements Runnable {

    private final AtomicInteger counter;

    DoThread(AtomicInteger counter) {
        this.counter = counter;
    }

    public void run() {
        counter.incrementAndGet();
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        AtomicInteger shared = new AtomicInteger(0);

        Thread t1 = new Thread(new DoThread(shared));
        Thread t2 = new Thread(new DoThread(shared));

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println(shared.get()); // Prints 2
    }
}

答案 1 :(得分:8)

代码很有用。

如果您使用的是匿名类,则可以将变量声明为final,并且可以在匿名类中访问它们。

public void main(String[] args) {
    final int myvar = 0;
    new Thread(new Runnable() {
        public void run() {
            System.out.println("myvar: "+myvar);
        }
    }).start();
}

答案 2 :(得分:2)

您需要传递对共享值的引用。如果它不是引用,则需要将其更改为AtomicReference,AtomicInt等或您要共享的值的数组。

答案 3 :(得分:0)

这是PassByRef更有效的地方。将变量引用传递给两个可运行的实例。多数民众赞成......从那时起,它可以在你的run方法中引用。

例如:

线程th1 =新线程(Myrunnable(varRef))。同样适用于其他线程