Java多线程信号量

Java多线程信号量,java,multithreading,Java,Multithreading,计数器变量不能准确反映增量的多少倍 方法被调用。为什么不呢?如何修复?(您不必编写代码, 用英语就行了。) 原件: import java.util.*; import java.lang.*; import java.io.*; class Foopadoop { public static int counter = 0; public static void main(String[] args) throws Exception { Runnable r = new Runn

计数器变量不能准确反映增量的多少倍 方法被调用。为什么不呢?如何修复?(您不必编写代码, 用英语就行了。)

原件:

import java.util.*;
import java.lang.*;
import java.io.*;


class Foopadoop
{
public static int counter = 0;
public static void main(String[] args) throws Exception {
    Runnable r = new Runnable() {
        public void run() {
            while(true){
                counter++;
            }
        }
    };
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
}
}
我的,我添加了一个信号灯,但我不确定我是否做得对,或者我应该使用锁

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.Semaphore;

class Foopadoop
{
public static int counter = 0;
Semaphore lock = new Semaphore(0);
public static void main(String[] args) throws Exception {
    Runnable r = new Runnable() {
        try{public void run() {
            while(true){
                counter++;
                lock.acquire();
            }
        }
       }finally{
         lock.release();
        }
    };
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
}
}

这不是使用
信号灯的方式

您在访问共享资源之前获取它,并在以下情况下释放它:

while (true) {
  try {
    lock.acquire();
    counter++;
  } finally {
    lock.release();
  }
}
由于您首先获得了
许可证,您还需要至少一个许可证,否则就没有什么需要获得的了:

static Semaphore lock = new Semaphore(1);
while (true) {
  synchronized (Foopadoop.class) {
    counter++;
  }
}
synchronized
块比
信号量更容易:

static Semaphore lock = new Semaphore(1);
while (true) {
  synchronized (Foopadoop.class) {
    counter++;
  }
}
或原子整数:

static AtomicInteger counter = new AtomicInteger();

// ...

while (true) {
  counter.getAndIncrement();
}

您还可以在while循环中添加Thread.sleep(ms),这样它将暂停当前线程一段时间,并开始执行其他线程。否则,当前线程可能会以自私的方式运行(自私线程)。

如果您要解释为什么该线程不工作,它会是-代码是否错误,因为线程正在多次初始化线程,因此计数器=0;但是该方法运行了两次?不,这是错误的,因为您在获取信号量之前访问了共享资源。信号量的要点是强制对变量进行互斥访问。也因为你在发布之前获得了多次。因为您试图在没有许可证的情况下获取信号量。我指的是原始问题,而不是我的代码版本。在原始版本中,
计数器仅在类加载时初始化一次。问题是
计数器的更新不能保证在线程之间可见;此外,它的值不能保证原子递增。因此,要解决我说的这是否是一个有效的答案/解决方案:我们需要使用锁或信号量来阻止其中一个线程,因此计数器将初始化两次?