2 u013179958 u013179958 于 2016.04.11 22:12 提问

懂java中lock锁的请进
 package thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Foo {

    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    private final Lock r = rwl.readLock();

    private final Lock w = rwl.writeLock();

    public void read() {
        try {
            r.lock();
            Thread.sleep(1000);
            System.out.println("read...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            r.unlock();
        }

    }

    public void wirte() {

        try {
            w.lock();
            Thread.sleep(1000);
            System.out.println("writing...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            w.lock();
        }
    }
}

上面是我在书上看到的代码

书上说让我写一个实现runnable接口的类
然后测试读写锁

我没明白,谁能解释下

2个回答

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.04.12 13:20
已采纳

首先,你这个Foo对象必须是被多个线程共享的,然后定义两个任务,一个执行读操作,另一个任务执行写操作,然后定义2个写线程,5个读线程,测试这些线程分别执行读、写操作时不同锁的特点。
其次,你的这个Foo类定义的write的finally分支错误了,应该是w.unlock()才对,稍微修正下你的Foo代码,输出当前线程的名称:

 import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Foo {

    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    private final Lock r = rwl.readLock();

    private final Lock w = rwl.writeLock();

    // 读锁,允许同时N个线程进行读操作,不存在竞争
    public void read() {
        try {
            r.lock();
            Thread.sleep(10000);
            System.out.println(Thread.currentThread().getName() + " read...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            r.unlock();
        }

    }

    //写锁,同时允许一个线程写,明显能看到互斥等待
    public void wirte() {

        try {
            w.lock();
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + " writing...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            w.unlock();
        }
    }
}

定义读任务:

 public class LockReadTask implements Runnable{

    private Foo source;

    public LockReadTask(Foo source){
        this.source = source;
    }

    @Override
    public void run() {
        source.read();
    }

}

定义写任务:

 public class LockWriteTask implements Runnable{
    private Foo source;

    public LockWriteTask(Foo source){
        this.source = source;
    }

    @Override
    public void run() {
        source.wirte();
    }
}

测试代码,定义2个写线程,看写锁的竞争状态;4个读线程,读锁步存在竞争。

 public class Main {
    public static void main(String[] args) {
        //定义共享数据源
        Foo source = new Foo();

        //开启2个写线程:能明显看到t1,t2写线程之间的互斥等待
        Thread t1 = new Thread(new LockWriteTask(source));
        t1.setName("write-Thread-1");
        Thread t2 = new Thread(new LockWriteTask(source));
        t2.setName("write-Thread-2");
        t1.start();
        t2.start();

        //开启5个读线程:读锁,允许同时N个线程进行操作,可以看到读打印操作同时秒出
        Thread rt1 = new Thread(new LockReadTask(source));
        rt1.setName("read-Thread-1");
        Thread rt2 = new Thread(new LockReadTask(source));
        rt2.setName("read-Thread-2");
        Thread rt3 = new Thread(new LockReadTask(source));
        rt3.setName("read-Thread-3");
        Thread rt4 = new Thread(new LockReadTask(source));
        rt4.setName("read-Thread-4");

        rt1.start();
        rt2.start();
        rt3.start();
        rt4.start();
    }
}   

可以看到测试结果:写线程之间有竞争,输出信息由先后;而都线程之间的读锁匙共享的,没有竞争,所以输出是同时秒出的。

wojiushiwo945you
wojiushiwo945you 回复据说名字太长不容易被发现: 谢谢。
2 年多之前 回复
u013179958
u013179958 回复毕小宝: 赞一个
2 年多之前 回复
wojiushiwo945you
wojiushiwo945you 读写锁真正需要测试的是,某个线程获取写锁时,其他线程不能读、不能写;而某个线程获取读锁时,其他线程仍然还可以读,即还可以获取读锁。
2 年多之前 回复
caozhy
caozhy   Ds   Rxr 2016.04.11 23:46

一般经典的例子就是开两个线程,给一个共有的变量累加。每个线程比如各累加10万次。按理说结果应该是20万。
但是如果你不同步线程,结果就会小于20万。

u013179958
u013179958 那我想测一测我的这个例子,我应该怎么么做?
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
Java中的锁-Lock接口解析
提到java中的锁,相信大家都知道它是用来控制多个线程访问共享资源的方式(即锁能防止多个线程同时访问空享资源而出现线程安全问题)。在实践过程中使用最多的也最常见的锁就是 synchronized 在jdk1.5之前也仅仅有这一种锁而已。在jdk1.5之后,并发包中新增了Lock接口
java学习笔记之多线程的锁接口Lock
众所周知,多线程的弊端是会使代码受到并发访问的干扰,解决的办法就是同步机制。同步的两种常见形式分别是同步代码块和同步函数,两种形式的锁都是隐式锁,前者持有的锁可以是任意对象,后者持有的锁是默认的this。 从JDK1.5开始,根据面向对象的思想,将锁封装了起来,对外提供Lock接口,并提供了对锁的显式操作。Lock接口的出现比synchronized有更多的操作,是同步的替代。   将锁单独封
java锁的Lock的几种用法
转载:https://segmentfault.com/q/1010000005602326 package concurrent; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.lo
java Lock(显示锁)
1.显示锁与内置锁对比 内置锁在代码块调用结束后会自动释放锁,但是显示锁必须自己控制加锁和释放锁,因此使用显示锁更加危险(忘记释放锁)。 内置锁不支持中断,阻塞的线程会一直等待直到拥有锁。而显示锁支持中断并且在处理锁的不可用问题上更加灵活(例如调用tryLock不会阻塞并且可以定时和轮询)。 显示锁并不能代替内置锁,只有当内置锁不能满足需求是才可以考虑显示锁。内置锁要比显示锁更安全,内置锁作为JVM
java锁机制,LOCK的实现类
1.synchronized --把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性(atomicity)和 可见性(visibility)。 1.1 原子性 --原子性意味着个时刻,只有一个线程能够执行一段代码,这段代码通过一个monitor object保护。从而防止多个线程在更新共享状态时相互冲突。 1.2 可见性 --可见性则更为微妙,它要对付内
java同步锁中synchronized和Lock接口类的区别
Lock提供了和sychronized类似的同步功能,只是在使用时需要显示地获取和释放锁。虽然Lock缺少了sychronized隐式获取释放锁的便捷性,但是却拥有了锁获取与是释放的可操作性、可中断的获取锁以及超时获取锁等多种sychronized所不具备的同步特性 Lock接口提供的sychronized所不具备的主要特性 特性 描述 尝试
Java锁----Lock实现原理
Lock完全用Java写成,在java这个层面是无关JVM实现的。 在java.util.concurrent.locks包中有很多Lock的实现类,常用的有ReentrantLock、ReadWriteLock(实现类ReentrantReadWriteLock),其实现都依赖java.util.concurrent.AbstractQueuedSynchronizer类,实现思路都大同小
Java并发编程系列之十六:Lock锁
Lock锁简介Lock锁机制是JDK 5之后新增的锁机制,不同于内置锁,Lock锁必须显式声明,并在合适的位置释放锁。Lock是一个接口,其由三个具体的实现:ReentrantLock、ReetrantReadWriteLock.ReadLock 和 ReetrantReadWriteLock.WriteLock,即重入锁、读锁和写锁。增加Lock机制主要是因为内置锁存在一些功能上局限性。比如无法中
java并发编程---synchronized和lock两种锁的比较
性能比较     在JDK1.5中,synchronized是性能低效的。因为这是一个重量级操作,它对性能最大的影响是阻塞的是实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并发性带来了很大的压力。相比之下使用Java提供的Lock对象,性能更高一些。多线程环境下,synchronized的吞吐量下降的非常严重,而ReentrankLock则能基本保持在同一个比较稳定的
Java多线程-Lock锁的使用,以及生产者和消费者的实现
本文中将主要介绍Java多线程编程基础中的Lock锁对象的使用,以及如何一步一步实现Java代码的生产者与消费者; 1、Java中如何使用Lock锁以及死锁问题的描述 2、Java实现生产者与消费者的过程(一步一步优化的步骤) 1、Java中如何使用Lock锁以及死锁问题的描述