下面的代码没有给出同步输出。
public class MultiThr implements Runnable{
public static void main(String[] args) {
for(int i = 0;i < 5;i++){
new Thread(new MultiThr()).start();
}
}
@Override
public void run() {
increment();
}
public synchronized void increment(){
for(int i=0;i<10;i++){
System.out.println(i);
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
有人可以解释一下如何在 increment()方法上获取对象锁吗?
答案 0 :(得分:0)
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) {}
}
}
}
}
答案 1 :(得分:-1)
您的increment()方法已同步。您的问题是它是Runnable的一部分。更多的是,你的计数器变量i是一个局部变量,因此即使没有synchronized关键字,每个线程也会拥有它自己的i副本。 我建议你做的是创建一个类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,只需确保将相同的实例传递给每个线程。