【问题标题】:Passing variable into methods (Java)将变量传递给方法(Java)
【发布时间】:2012-02-09 11:22:00
【问题描述】:

我是 Java 新手,但遇到了问题。我已经从 Android 教程中复制了一些代码,现在我想将一个整数变量传递给方法 run(),这样我就可以为每个循环递增它,然后在后台线程之外捕获它。我该怎么做?

int gg= 0;    
Thread background = new Thread(new Runnable() {
                    public void run() {
                        try {

                            while (pBarDialog.getProgress() <= 100) {

                                Thread.sleep(100);
                                gg++; // the increment here
                                progressHandler.sendMessage(progressHandler
                                        .obtainMessage());


                            }
                            if (pBarDialog.getProgress() == 100) {
                                pBarDialog.dismiss();

                            }

                        } catch (java.lang.InterruptedException e) {
                            // if something fails do something smart
                        }
                    }

                });
          //catch gg here

【问题讨论】:

  • “捕获”变量是什么意思?顺便说一句,我认为 pBarDialog.dismiss() 应该在 UI 线程上调用,即在 Handler 中。
  • 捕捉我的意思是打印出来。
  • 任何你想传递给内部类的东西都可以使用“final”来完成(但是如果你想修改它,你必须将变量的值复制到另一个)

标签: java android variables methods


【解决方案1】:

您不能为 run() 方法指定参数。您可以将 int 变量声明为字段并在内部类中使用。

public class TestActivity extends Activity
{
   private volatile int no;
   .....

}

编辑:(来自@alf 的建议)您可以将volatile modifier 与字段一起使用,以便所有其他线程可以立即看到更改的值。

【讨论】:

  • 请注意最好是volatile 以确保可见性。
  • 他必须使用 volatile,否则计数器值没有意义。
【解决方案2】:

拥有自己的类并使用其构造函数传递计数器,我没有尝试过,但我会从这样的开始:

class MyThread implements Runnable {

   private volatile int counter;

   public MyThread( int counter ) {
       this.counter = counter;
   }

   public void run() {
   ...
   }

   public getCounter() {
      return counter;
   }
}

MyThread mt = new MyThread( 10 );
Thread t = new Thread( mt );
t.start();

// after some time
t.getCounter();

【讨论】:

  • 为什么使用Integer 而不是int?计数器应该是易失的,或者应该始终从同步块访问。否则,即使后台线程将其设置为 1000000,主线程也可能会将 10 视为值。
  • @JBNizet 谢谢我修好了,我正在上班的路上,因为我认识到我的失败。幸运的是,我并没有像我想象的那样被严重否决。
【解决方案3】:
private volatile int gg;

public void myMethod() {
    Thread background = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                while (pBarDialog.getProgress() <= 100) {
                    Thread.sleep(100);
                    gg++; // the increment here
                    progressHandler.sendMessage(progressHandler.obtainMessage());
                }
                if (pBarDialog.getProgress() == 100) {
                    pBarDialog.dismiss();
                }
            } catch (java.lang.InterruptedException e) {
                // if something fails do something smart
            }
        }

    });

    System.out.println(gg);
}

【讨论】:

  • 你不能 ++ 一个最终变量,可以吗?
  • 我从来没有遇到过问题。我已经编辑了我的答案以包含一个替代方案。
  • 调用 this.gg = gg 不起作用,因为 gg 是最终的。既然目标是改变它的价值,你为什么要把它定为最终版本?
  • 你也不能 ++ 一个最终参数。
  • 现在几乎是正确的。 gg 必须是可变的,否则主线程可能总是看到初始值。并且使用公共字段是不好的做法。
【解决方案4】:

如果我是你,我会研究AtomicInteger,即incrementAndGet() 方法。

使gg 成为一个字段确实会让线程访问gg,而volatile 将使更改可见,但是因为你的意图不是清楚,我不能确定你没有其他线程增加相同的值:你没有原子性,所以只要你有多个线程在做gg++,你'可能会得到错误的结果。

【讨论】:

    猜你喜欢
    • 2012-08-21
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多