[英]Basic multi-threading issue
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万。
另一方面,当增量方法定义为静态时,它可以正常工作。
据我所知,所有Process对象都只有一个增量函数。为什么我必须将其声明为静态方法呢?
谢谢
声明为静态将导致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++;
}
}
编辑:回答鲁基的问题。
class Process{
public static synchronized void increment() { counter++; }
}
等价于
class Process{
public void increment() {
synchronized(Process.class){
counter++;
}
}
您可能需要用AtomicInteger计数器替换int计数器-这样,您可以从方法中删除synced关键字,并且该方法是静态方法还是实例方法都没有关系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.