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