【发布时间】:2018-08-02 20:58:04
【问题描述】:
我正在尝试多线程和同步,所以我创建了这个在所有线程之间共享的简单对象:
public class SharedObject {
private int count = 0;
public synchronized int getCount(){
return count;
}
public synchronized void incrementCount(){
count++;
}
}
并且以这种方式被3个线程访问:
public static void main(String[] args) throws Exception {
SharedObject sharedObject = new SharedObject();
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
Runnable task = () -> {
for(int i = 0; i < 10; i++){
System.out.println("Thread : " + Thread.currentThread().getName()
+ " count : " + sharedObject.getCount());
sharedObject.incrementCount();
try{
Thread.currentThread().sleep(2000);
}
catch (Exception e){}
}
};
executor.submit(task);
executor.submit(task);
executor.submit(task);
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
System.out.println("Final : " + sharedObject.getCount());
}
我的输出如下:
Thread : pool-1-thread-2 count : 0
Thread : pool-1-thread-1 count : 0
Thread : pool-1-thread-3 count : 0
Thread : pool-1-thread-3 count : 3
Thread : pool-1-thread-2 count : 3
Thread : pool-1-thread-1 count : 3
Thread : pool-1-thread-2 count : 6
Thread : pool-1-thread-1 count : 6
Thread : pool-1-thread-3 count : 6
...
如果我的理解是正确的(如果我错了请纠正我),这是因为:
第一个线程调用
getCount(),获得方法上的锁,一旦他打印计数值,释放锁,然后由第二个线程调用getCount(),然后继续与最后一个线程当所有 3 个线程都调用完
getCount()后,它们现在都在调用incrementCount()并且由于该方法是同步的,因此每个线程在增加计数之前都会看到更新的值,这就解释了为什么我们会看到跳转输出中的+3-
一旦一个线程完成,它就会在自己身上调用
李>sleep(2000),但是由于调用速度非常快,所以三个线程似乎同时开始和停止休眠
但是,当我删除 sleep(2000) 时,我得到以下输出:
Thread : pool-1-thread-3 count : 0
Thread : pool-1-thread-2 count : 0
Thread : pool-1-thread-1 count : 0
Thread : pool-1-thread-2 count : 2
Thread : pool-1-thread-3 count : 1
Thread : pool-1-thread-2 count : 4
Thread : pool-1-thread-1 count : 3
Thread : pool-1-thread-2 count : 6
Thread : pool-1-thread-3 count : 5
Thread : pool-1-thread-2 count : 8
Thread : pool-1-thread-1 count : 7
Thread : pool-1-thread-2 count : 10
Thread : pool-1-thread-3 count : 9
Thread : pool-1-thread-2 count : 12
Thread : pool-1-thread-1 count : 11
Thread : pool-1-thread-2 count : 14
我不明白这怎么会发生。例如,如果thread-2 在他之前看到它等于 2 并增加它,thread-3 怎么能看到它等于 1?
任何解释都可以帮助我更好地理解多线程同步环境中的 Java。感谢您的宝贵时间。
【问题讨论】:
-
单个线程在
getCount()调用和println()调用之间可能会有延迟,在此期间其他线程也会调用getCount()和println()。如果我编写这个代码,我将只有incrementCount(int delta),它返回count的当前值,并且可以传递0的增量。
标签: java multithreading concurrency synchronization synchronized