【问题标题】:Basic multi-threading issue基本的多线程问题
【发布时间】:2013-04-09 23:02:57
【问题描述】:
package demo5;

class Process extends Thread {

static int counter = 0;

public static  synchronized void increment() { counter++; }

public void run() {
    for (int i = 0; i < 1000000; i++)
    {
        increment();
    }
    System.out.println("Done.");
  }
}

public class App {

public static void main(String[] args) throws InterruptedException {
    Process p1 = new Process();
    Process p2 = new Process();
    p1.start();
    p2.start();

    p1.join();
    p2.join();

    System.out.println("Value of count is :" + p1.counter);

}

}

如果我将增量​​函数声明为非静态函数,那么最后计数器的值不会是 200 万。

另一方面,当增量方法定义为静态时,它可以正常工作。

据我所知,所有 Process 对象只有一个增量函数.. 那么为什么我必须将其声明为静态方法..?

谢谢

【问题讨论】:

  • 你确定你的意思是counterstatic吗?
  • 您甚至可以在计数器中添加瞬态关键字并删除同步,它会起作用。
  • @shevchik Transient 不会影响它。你的意思是易变的吗?即使那样也行不通。
  • 约翰,你是对的,易变的。为什么不工作?
  • 因为一个增量是三个操作。读增量写。 Volatile 有助于提高单个操作的可见性,但由于增量是一种复合物,它无法对其做任何事情。

标签: java multithreading


【解决方案1】:

将其声明为静态将导致synchronized 锁定 Process.class 实例。所以所有运行的线程都会阻塞increment 方法中的对象。删除静态将导致每个线程仅阻塞 Thread 实例(在您的情况下有两个)。

因此,您的 counter 变量正在并行递增,并且正如多次指出的那样,int 递增不是线程安全的。

As far as I know there will be only ONE increment function for all the Process objects

Process 类有一个增量函数,但是同步是在 Object 上完成的,而不是在方法上完成的:

class Process{
     public synchronized void increment() { counter++; }
}

等同于:

class Process{
     public void increment() { 
           synchronized(this){
                  counter++; 
            }
}

编辑:回答 Rouki 的问题。

class Process{
     public static synchronized void increment() { counter++; }
}

等价于

class Process{
     public void increment() { 
           synchronized(Process.class){
                  counter++; 
            }
}

【讨论】:

  • Ehm,你想告诉我编译器为每个创建的对象创建所有类成员函数..? (对java有点新,之前用cpp开发过)
  • @Rouki 抱歉让我说得更好。
  • 好吧..我想开始明白了。所以当我将此方法声明为静态(意味着它现在没有 THIS)时,“Synchronized(this)”现在会是什么样子?
  • @Rouki 已更新。因此,由于始终存在一个 Process.class 实例,因此锁将阻止任何数量的尝试递增的实例。
【解决方案2】:

您可能希望将您的 int 计数器替换为 AtomicInteger 计数器 - 这样您可以从方法中删除同步关键字,并且该方法是静态方法还是实例方法无关紧要。

【讨论】:

    猜你喜欢
    • 2011-01-27
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    相关资源
    最近更新 更多