ReentrantLock无法正常工作 [英] ReentrantLock doesn't work out

查看:151
本文介绍了ReentrantLock无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么代码无法正常工作.问题在于ReentrantLock不会锁定ThreadClass.run()中的方法调用.

资源类,假定哪些方法已锁定在ThreadClass中

public class ResourceClass {

    private int i; 

    public void setIncrement() {
        i++;
    }

    public int getIncrement() {
        return i;
    }

}

线程类

public class ThreadClass implements Runnable {

    private ResourceClass resource;
    private ReentrantLock reentrantLock = new ReentrantLock();

    ThreadClass(ResourceClass r) {
        resource = r;
    }

    public void run() {
        reentrantLock.lock();
        try {
            resource.setIncrement();
            System.out.println(resource.getIncrement());
        } finally {
            reentrantLock.unlock();
        }
    }

}

主要班级

public class MainClass {

    public static void main(String[] args) {

        ResourceClass resource = new ResourceClass();

        Thread thread = new Thread(new ThreadClass(resource));
        thread.start();
        Thread thread2 = new Thread(new ThreadClass(resource));
        thread2.start();
        Thread thread3 = new Thread(new ThreadClass(resource));
        thread3.start();
    }

} 

假定在run()中被锁包围的代码必须是同步的",因此导致只有一个线程可以访问Resourse-object的方法.实际上,事实并非如此.该代码产生重复的数字,这意味着两个线程可以同时访问这些方法.我知道这确实是一个简单的问题,但我不明白该如何解决.感谢您的帮助.

更新:

我明白了.那段代码工作得很好(我删除了setIncrement()并将所有相关逻辑放入getIncrement()中):

public int getIncrement() {
        reentrantLock.lock();
        int incrementResult = i++;
        reentrantLock.unlock();
        return incrementResult;
} 

解决方案

您正在为每个可运行的对象创建一个新的ReentrantLock,这意味着没有同步.您将需要与每个Runnable实例共享一个锁.

I can't figure out why the code doesn't work properly. The problem is that ReentrantLock doesn't lock methods invocation in ThreadClass.run()

Resource-class which methods are assumed to be locked in ThreadClass

public class ResourceClass {

    private int i; 

    public void setIncrement() {
        i++;
    }

    public int getIncrement() {
        return i;
    }

}

Thread-class

public class ThreadClass implements Runnable {

    private ResourceClass resource;
    private ReentrantLock reentrantLock = new ReentrantLock();

    ThreadClass(ResourceClass r) {
        resource = r;
    }

    public void run() {
        reentrantLock.lock();
        try {
            resource.setIncrement();
            System.out.println(resource.getIncrement());
        } finally {
            reentrantLock.unlock();
        }
    }

}

Main-class

public class MainClass {

    public static void main(String[] args) {

        ResourceClass resource = new ResourceClass();

        Thread thread = new Thread(new ThreadClass(resource));
        thread.start();
        Thread thread2 = new Thread(new ThreadClass(resource));
        thread2.start();
        Thread thread3 = new Thread(new ThreadClass(resource));
        thread3.start();
    }

} 

It is supposed that the code surrounded by lock in run() must be "synchronised" thus results that only one thread has access to the methods of Resourse-object. At practice it doesn't. The code results repeated numbers which means that two threads have access to the methods at the same time. I know that it is really simple issue but I can't understand how to solve it. Thanks for assistance.

Update:

I got that. That piece of code works just fine (I deleted setIncrement() and put all the relevant logic into getIncrement()):

public int getIncrement() {
        reentrantLock.lock();
        int incrementResult = i++;
        reentrantLock.unlock();
        return incrementResult;
} 

解决方案

You are creating a new ReentrantLock per runnable meaning there is no synchronization. You will need to share the one lock with each Runnable instance.

这篇关于ReentrantLock无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆