使用同步方法获取对象锁定
这个问题在这里已经有了答案:
synchronized关键字的这种用法会导致该方法获取该方法被调用的对象的锁定。 由于您有5个MultiThr
对象,这是5个不同的被锁定的对象。
有很多选项可以解决这个问题,例如,您可以创建一个要在所有MultiThr
对象之间共享的对象:
public class MultiThr implements Runnable{
private static final Object lock = new Object();
public static void main(String[] args) {
for(int i = 0;i < 5;i++){
new Thread(new MultiThr()).start();
}
}
@Override
public void run() {
increment();
}
public void increment(){
synchronized (lock) {
for(int i=0;i<10;i++){
System.out.println(i);
try {
Thread.sleep(400);
} catch (InterruptedException e) {}
}
}
}
}
你的increment()方法是同步的。 你的问题是它是你的Runnable的一部分。 更重要的是,你的计数器变量i是一个局部变量,所以每个线程都会拥有它自己的副本,即使没有synchronized关键字也是如此。 我建议你做的是创建一个MyConter类,如:
class MyCounter {
private int i;
public MyCounter () {
i = 0;
}
public int getCounter() {
return i;
}
public void increment() {
i++;
}
}
然后将其作为参数传递给MultiThr构造函数:
public class MultiThr implements Runnable{
private MyCounter counter;
public MultiThr(MyCounter counter) {
this.counter = counter;
}
@Override
public void run() {
increment();
}
public synchronized void increment(){
for(int i=0;i<10;i++){
counter.increment();
System.out.println(counter.getCounter());
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// Do not do just e.printStackTrace()
Thread.currentThread().interrupt()
}
}
}
public static void main(String[] args) {
for(int i = 0;i < 5;i++){
new Thread(new MultiThr()).start();
}
}
}
或者您可以使用AtomicInteger而不是MyCounter,只要确保将相同的实例传递给每个线程即可。
链接地址: http://www.djcxy.com/p/91859.html