通过同步方法获取对象锁
通过同步方法获取对象锁
下面的代码没有给出同步的输出。
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) { e.printStackTrace(); } } } }
有人可以解释一下如何在 `increment()` 方法上获取对象锁吗?
问题的原因是increment()方法是同步的,但是它是Runnable的一部分。另外,计数器变量i是一个局部变量,所以即使没有同步关键字,每个线程也会有自己的i的副本。
解决方法是创建一个名为MyCounter的类,并将其作为参数传递给MultiThr构造函数。MyCounter类有一个私有变量i和相应的getter和setter方法。在increment()方法中,使用synchronized关键字来确保同一时间只有一个线程能够执行该方法。然后,在MultiThr的run()方法中调用increment()方法。
另一种解决方法是使用AtomicInteger而不是MyCounter类。只需确保将同一个AtomicInteger实例传递给每个线程即可。
下面是修复后的代码示例:
class MyCounter { private int i; public MyCounter () { i = 0; } public int getCounter() { return i; } public synchronized void increment() { i++; } } public class MultiThr implements Runnable { private MyCounter counter; public MultiThr(MyCounter counter) { this.counter = counter; } public void run() { increment(); } public void increment() { for(int i=0; i<10; i++) { counter.increment(); System.out.println(counter.getCounter()); try { Thread.sleep(400); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } public static void main(String[] args) { MyCounter counter = new MyCounter(); for(int i = 0; i < 5; i++) { new Thread(new MultiThr(counter)).start(); } } }
以上代码中,我们创建了一个MyCounter实例作为计数器,并将其传递给每个MultiThr线程。每个线程都会调用increment()方法来递增计数器,并打印出当前计数器的值。通过在increment()方法上添加synchronized关键字,我们确保了每个线程在执行该方法时都会获取对象锁,从而避免了多个线程同时修改计数器的问题。
问题的原因是使用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(); } } 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) {} } } } }
以上代码通过创建一个静态的共享对象lock,并在increment方法中使用synchronized关键字锁定这个共享对象,实现了多个MultiThr对象之间的同步。