基本的多线程问题

时间:2013-04-09 14:43:35

标签: java multithreading

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);

}

}

如果我将增量​​函数声明为NON-STATIC函数,则结尾处的计数器值不会是200万。

另一方面,当increment方法定义为static时,它可以正常工作。

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

感谢

2 个答案:

答案 0 :(得分:7)

将其声明为静态将导致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++; 
            }
}

答案 1 :(得分:1)

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