从线程更新java对象的属性?

时间:2017-08-19 19:46:32

标签: java

变量var的值始终为0. IT几乎就像从未调用过该方法一样。我希望能够从线程内部更改val的值,如果我调用getVal(),我希望能够访问新值。

public class Test1 {
    private int val;

    public Test1() {
        val=0;
    }

    public void changeVal() {

        new Thread(new Runnable() {
            public void run() {
                val=1;
            }
        }).start();
    }

    public int getVal() {
        return this.val;
    }

    public static void main(String[]args) {
        Test1 x=new Test1();
        x.changeVal();
        System.out.println("VAl: "+x.getVal() );
    }
}

5 个答案:

答案 0 :(得分:3)

值已更改,但getVal()(在大多数情况下)在方法' run'中var = 1之前执行。执行顺序由线程调度程序控制,但正如Johnny Mopp所述,添加.join()将修复它。

  public void changeVal() throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                val = 1;

            }

        });
        t.start();
        t.join();

    }

    public static void main(String[] args) throws InterruptedException {
        Test1 x = new Test1();
        x.changeVal();

        System.out.println("VAl: " + x.getVal());
    }

答案 1 :(得分:0)

您已在声明

之间设置竞争条件
  x.changeVal();

 System.out.println("VAL: "+x.getVal() );

尝试将以下代码放在上述两个语句之间。

    try {
        Thread.sleep(100);
    }
    catch (Exception e) {
        System.out.println("Exception: " + e);
    }

这使您的新线程有机会在到达println语句之前建立。

答案 2 :(得分:0)

您需要更改主要方法,如下所示:

public static void main(String[]args)
 {
    Test1 x=new Test1();
    x.changeVal();
   try {
        Thread.sleep(100);//sometime here 
    }
    catch (Exception e) {
        System.out.println("Exception: " + e);
    }
    System.out.println("VAl: "+x.getVal() );

 }

您可以使用Thread.join();changeVal()方法中使用子线程加入主线程。

答案 3 :(得分:0)

一个灵魂可以使用ReentrantLock

将其定义为类成员变量

Lock lock = new ReentrantLock();

在changeVal中使用此锁

public void changeVal() throws InterruptedException {
    if (lock.tryLock()) {
        try {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    val = val + 1;
                }
            }).start();

        } finally {
            lock.unlock();
        }
    }

}

答案 4 :(得分:-1)

您需要创建变量volatile,如果您希望在main方法中打印变量之前更改变量,则需要安排一些同步或锁定。这使线程毫无意义。

很难看出其中的任何一点。