java - ReentrantLock 中的困惑

标签 java multithreading

我试图了解 Java 中 ReentrantLock 的内部工作原理。

我创建了一个示例,例如:-

package com.thread.trylock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockingDemo {

    final Lock lock = new ReentrantLock();

    public static void main(final String... args) {

        new  ReentrantLockingDemo().go();

    }

    private void go() {

        Runnable run1 = newRunable();
        Thread t1 = new Thread(run1, "Thread1");
        System.out.println(run1.hashCode());
        t1.start();

        Runnable run2 = newRunable();
        Thread t2 = new Thread(run2, "Thread2");
        System.out.println(run2.hashCode());
        t2.start();

    }

    private Runnable newRunable() {

        return new Runnable() {

            @Override

            public int hashCode() {

                return super.hashCode();

            }

            @Override

            public void run() {

                do {

                    try {

                        if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {

                            try {

                                System.out.println("locked thread "

                                        + Thread.currentThread().getName());


                                Thread.sleep(1000);


                            } finally {

                                lock.unlock();

                                System.out.println("unlocked locked thread "

                                        + Thread.currentThread().getName());

                            }

                            break;

                        } else {

                            System.out.println("unable to lock thread "

                                    + Thread.currentThread().getName()

                                    + " will re try again");

                        }

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                } while (true);

            }     

        };

    }

}



//Output something like this (which may be slightly different on your machine)

locked thread Thread2

unable to lock thread Thread1 will re try again

locked thread Thread1

unlocked locked thread Thread2

unlocked locked thread Thread1

现在我的问题是有2个线程对象和2个可运行对象和2个线程。每个线程都应该在自己的堆栈帧上为不同的可运行对象运行 run 方法。如果每个线程使用不同的可运行对象在堆栈上运行自己的 run 方法,则输出应该不同。

我见过一些示例,其中我们创建了几个线程,然后将共享对象传递到这些线程上,然后在该共享对象的方法中锁定和解锁。这里的对象不被共享。有 2 个可运行对象传递给 2 个线程对象,但可运行对象表现为共享对象。

您能否解释一下可能导致此输出的原因是什么?或者可以提供一些相同的说明

谢谢

最佳答案

Here the object is not shared

两个线程都运行自己的 Runnable 实例是正确的,因此两个线程不共享公共(public) Runnable。

但是两个 Runnable 实例都使用封闭类的共享对象,这就是锁对象。所以他们在这个对象的帮助下相互同步。只要另一个线程通过调用持有锁,一个线程就会被阻塞

lock.tryLock(500, TimeUnit.MILLISECONDS)

为什么两个 Runnable 实例都可以访问被定义为类 ReentrantLockingDemo 的私有(private)变量的锁对象,解释如下 Anonyomous Classes

所以当你写

private Runnable newRunable() {

    return new Runnable() {...};
}

您创建一个继承自 Runnable 的匿名内部类的新实例,该内部类可以访问外部类的所有最终(或在 Java 8 中也所有有效的最终)字段。

因此,即使您没有显式地将共享对象传递给 Runnable 实例,它们也会使用共享对象进行同步,在本例中为锁定对象。

关于java - ReentrantLock 中的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31685716/

相关文章:

java - 如何在 Java 中创建自定义注释以允许参数具有指定范围内的值?

java - 两个不同长度的字符串可以有相同的哈希码吗?

c - c 中父子之间的 sigusr1

java - 处理许多客户端的最佳方法(使用线程?)

windows - 解决错误 R6016 - 线程数据空间不足

java - 使用相同的方法返回多个列表 Spring MVC

java - 当 jar 文件具有各种传出依赖项时,如何使用 IKVMC 将特定 JAR 文件转换为 DLL?

java - 通过 Java 使用 Drive API

c++ - QtConcurrent Map 不能使用类方法

android防弹toast方法