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对象只有一个递增函数..那么为什么我必须将它声明为静态方法..?
感谢
答案 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关键字,并且该方法是静态方法还是实例方法无关紧要。