Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当我们在方法中创建锁(同步块)对象时会发生什么? 公共类SampleExecutor服务{ 私有静态整数计数=0; 私有无效增量(){ 对象锁=新对象(); 已同步(锁定){ 计数++; } } 公共静态void main(字符串[]args){ ExecutorService ExecutorService=Executors.newFixedThreadPool(10); SampleExecutorService obj=新的SampleExecutorService(); 可运行任务=obj::增量; 对于(int i=0;i_Java_Multithreading_Concurrency_Synchronization_Executorservice - Fatal编程技术网

Java 当我们在方法中创建锁(同步块)对象时会发生什么? 公共类SampleExecutor服务{ 私有静态整数计数=0; 私有无效增量(){ 对象锁=新对象(); 已同步(锁定){ 计数++; } } 公共静态void main(字符串[]args){ ExecutorService ExecutorService=Executors.newFixedThreadPool(10); SampleExecutorService obj=新的SampleExecutorService(); 可运行任务=obj::增量; 对于(int i=0;i

Java 当我们在方法中创建锁(同步块)对象时会发生什么? 公共类SampleExecutor服务{ 私有静态整数计数=0; 私有无效增量(){ 对象锁=新对象(); 已同步(锁定){ 计数++; } } 公共静态void main(字符串[]args){ ExecutorService ExecutorService=Executors.newFixedThreadPool(10); SampleExecutorService obj=新的SampleExecutorService(); 可运行任务=obj::增量; 对于(int i=0;i,java,multithreading,concurrency,synchronization,executorservice,Java,Multithreading,Concurrency,Synchronization,Executorservice,上面程序的预期结果是1000,但由于我遵循了同步机制,所以它没有给出该结果。但是如果我们在类级实例变量中创建一个锁对象,它就可以正常工作。下面是正确的代码片段 public class SampleExecutorService { private static int count = 0; private void increment() { Object lock = new Object(); synchronized (lock) {

上面程序的预期结果是1000,但由于我遵循了同步机制,所以它没有给出该结果。但是如果我们在类级实例变量中创建一个锁对象,它就可以正常工作。下面是正确的代码片段

public class SampleExecutorService {
    private static int count = 0;

    private void increment() {
        Object lock = new Object();
        synchronized (lock) {
            count++;
        }   
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        SampleExecutorService obj = new SampleExecutorService();
        Runnable task = obj::increment;

        for (int i = 0; i < 1000; i++) {
            executorService.submit(task);

        }
        executorService.shutdown();

        try {
            executorService.awaitTermination(2, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("count : " + count);
    }
}
公共类SampleExecutor服务{
私有静态整数计数=0;
对象锁=新对象();
私有无效增量(){
//对象锁=新对象();
已同步(锁定){
计数++;
}   
}
公共静态void main(字符串[]args){
ExecutorService ExecutorService=Executors.newFixedThreadPool(10);
SampleExecutorService obj=新的SampleExecutorService();
可运行任务=obj::增量;
对于(int i=0;i<1000;i++){
执行器服务。提交(任务);
}
executorService.shutdown();
试一试{
执行人服务。等待终止(2,时间单位。分钟);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“计数:+count”);
}
}

我想知道,当我们在方法中创建锁对象时会发生什么?在方法内部创建锁对象和作为实例变量创建锁对象之间有什么区别

局部变量存储在线程堆栈上,并分别为每个线程创建。如果局部变量不是原语,则实例本身存储在堆上,但对对象的引用存储在线程堆栈上。这就是为什么局部变量是线程安全的

由于全局变量存储在堆上,并且由多个线程共享/可见,因此需要对它们进行同步

因此,在第一个示例中,您正在为每个线程创建新锁,因此多个线程仍然能够访问它


这是一篇关于Java内存模型的优秀文章

您正在为每个调用创建一个新的、单独的锁对象,因此实际上根本没有锁,因为每个调用都锁在不同的对象上。实际上,您将有10个线程在不进行任何同步的情况下同时修改计数器,从而为争用条件和可见性问题留出空间。每个方法调用都会创建自己的调用堆栈,因此在第一个示例中,锁是没有意义的。因为您只创建了一个
SampleExecutorService
的实例,区别在于1000个锁对象(在方法内部创建)与1个锁对象(用于
SampleExecutorService
实例)。谢谢!我能理解你的答案。这消除了我对这个问题的所有疑虑谢谢@xagaffar。但我有一个疑问,方法中的对象存储在堆中(所有对象都存储在堆中),对吗?我的观点正确吗?@Rajeshkumar技术上是的,对象本身存储在堆中,但对对象的本地引用(重要的是)存储在线程堆栈中。我会更新我的答案让它更清楚。谢谢:-)@xagaffar。你的回答很清楚,帮助我更好地理解了概念。你们分享的文章看起来解释得很好。
public class SampleExecutorService {
    private static int count = 0;
    Object lock = new Object();
    private void increment() {
        //Object lock = new Object();
        synchronized (lock) {
            count++;
        }   
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        SampleExecutorService obj = new SampleExecutorService();
        Runnable task = obj::increment;

        for (int i = 0; i < 1000; i++) {
            executorService.submit(task);

        }
        executorService.shutdown();

        try {
            executorService.awaitTermination(2, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("count : " + count);
    }
}