Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.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 如何使用可重入锁实现三个线程的同步?_Java_Multithreading - Fatal编程技术网

Java 如何使用可重入锁实现三个线程的同步?

Java 如何使用可重入锁实现三个线程的同步?,java,multithreading,Java,Multithreading,下面指定的代码段使用wait()和notify()方法同步三个线程,按顺序打印数字。但要求是使用可重入锁定机制实现相同的功能 class JoinTask { private int currentRank = 1; public void doJob(int rank, int printNo) { synchronized (this) { while (rank != currentRank) {

下面指定的代码段使用wait()和notify()方法同步三个线程,按顺序打印数字。但要求是使用可重入锁定机制实现相同的功能

class JoinTask {

    private int currentRank = 1;

    public void doJob(int rank, int printNo) {
        synchronized (this) {
            while (rank != currentRank) {
                try {
                    System.out.println("going to wait by thread:" + printNo);
                    wait();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            System.out.println("Job:" + printNo + " : " + currentRank);
            currentRank++;
            notifyAll();
        }
    }
}

public class ThreeThreadsPlay {

    public static void main(String[] args) {
        final JoinTask task = new JoinTask();

        Thread A = new Thread() {
            public void run() {
                int k = 1;
                for (int i = 1; i < 30; i++) {
                    task.doJob(k, 1);
                    k = k + 3;
                }}};

        Thread B = new Thread() {
            public void run() {
                int k = 2;
                for (int i = 1; i < 30; i++) {
                    task.doJob(k, 2);
                    k = k + 3;
                }}};

        Thread C = new Thread() {
            public void run() {
                int k = 3;
                for (int i = 1; i < 30; i++) {
                    task.doJob(k, 3);
                    k = k + 3;
                }}};
        C.start();
        B.start();
        A.start();
    }}
类连接任务{
私有int currentRank=1;
public void doJob(int-rank,int-printNo){
已同步(此){
while(秩!=当前秩){
试一试{
System.out.println(“将通过线程进行等待:+printNo);
等待();
}捕获(中断异常例外){
例如printStackTrace();
}
}
System.out.println(“作业:+printNo+:“+currentRank”);
currentRank++;
notifyAll();
}
}
}
公共类ThreadSplay{
公共静态void main(字符串[]args){
最终JoinTask任务=新JoinTask();
线程A=新线程(){
公开募捐{
int k=1;
对于(int i=1;i<30;i++){
任务doJob(k,1);
k=k+3;
}}};
线程B=新线程(){
公开募捐{
int k=2;
对于(int i=1;i<30;i++){
任务doJob(k,2);
k=k+3;
}}};
线程C=新线程(){
公开募捐{
int k=3;
对于(int i=1;i<30;i++){
任务。doJob(k,3);
k=k+3;
}}};
C.开始();
B、 开始();
A.开始();
}}
如何使用可重入锁定实现相同的功能


任何其他使用可重入锁定来提供这种机制的示例也会有所帮助。此外,在此上下文中提供的任何信息都将受到高度赞赏。

这里是一个使用
ReentrantLock/Conditional
的正确实现。请仔细注意这与您尝试的内容之间的差异。锁的获取和释放实际上应该在
try finally
块中处理,以避免锁被无限期保留,但您可以在其他问题中找到这样的示例

class JoinTask {

    private int currentRank = 1;
    final ReentrantLock l = new ReentrantLock();
    final Condition c = l.newCondition();

    public void doJob(int rank, int threadNumber) {
        l.lock();
        while(rank != currentRank) {
            c.await();
        }
        System.out.println("Job:" + threadNumber + " : " + currentRank);
        currentRank++;
        c.signalAll();
        l.unlock();
    }
}

努力
ReentrantLock
条件
与使用
synchronized
wait/notify
没有太大区别。我试过了。。但它失败了。因此,我发布了一些输入。与其只是给出一些声明,还不如提供一些帮助。这个词是“可重入的”,而不是“可重入的”,而且这些锁已经是可重入的。不清楚你在问什么。我同意这在有ReentrantLock的Condition类的帮助下可以很好地工作,并且就性能而言,与没有Condition的ReentrantLock相比是合适的,因为在后一种情况下,由于每个线程都将继续运行以获得机会,因此会消耗更多的时间,然而,在前一种情况下,它使用了等待和通知功能。谢谢你完全理解了答案!