美文网首页JUC编程-线程高级应用
JUC线程高级---读写锁和线程八锁

JUC线程高级---读写锁和线程八锁

作者: ZebraWei | 来源:发表于2018-05-30 20:08 被阅读27次

**版权声明:本文为小斑马伟原创文章,转载请注明出处!


读-写锁ReadWriteLock:ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有writer,读取锁可以由多个reader 线程同时保持。写入锁是独占的。

ReadWriteLock 读取操作通常不会改变共享资源,但执行写入操作时,必须独占方式来获取锁。对于读取操作占多数的数据结构。ReadWriteLock 能提供比独占锁更高的并发性。而对于只读的数据结构,其中包含的不变性可以完全不需要考虑加锁操作。

/*
 * 1. ReadWriteLock : 读写锁
 * 
 * 写写/读写 需要“互斥”
 * 读读 不需要互斥
 * 
*/
public class TestReadWriteLock {

public static void main(String[] args) {
    ReadWriteLockDemo rw = new ReadWriteLockDemo();
    
    new Thread(new Runnable() {
        
        @Override
        public void run() {
            rw.set((int)(Math.random() * 101));
        }
    }, "Write:").start();
    
    
    for (int i = 0; i < 100; i++) {
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                rw.get();
            }
        }).start();
    }
}

class ReadWriteLockDemo{

private int number = 0;

private ReadWriteLock lock = new ReentrantReadWriteLock();

//读
public void get(){
    lock.readLock().lock(); //上锁
    
    try{
        System.out.println(Thread.currentThread().getName() + " : " + number);
    }finally{
        lock.readLock().unlock(); //释放锁
    }
}

//写
public void set(int number){
    lock.writeLock().lock();
    
    try{
        System.out.println(Thread.currentThread().getName());
        this.number = number;
    }finally{
        lock.writeLock().unlock();
    }
}

线程八锁一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法
锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法
加个普通方法后发现和同步锁无关
换成两个对象后,不是同一把锁了,情况立刻变化。
所有的非静态同步方法用的都是同一把锁——实例对象本身,也就是说如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁,可是别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,所以毋须等待该实例对象已获取锁的非静态同步方法释放锁就可以获取他们自己的锁。

所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对象,所以静态同步方法与非静态同步方法之间是不会有竞态条件的。但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同步方法之间,只要它们同一个类的实例对象!

/*
 * 题目:判断打印的 "one" or "two" ?
 * 
 * 1. 两个普通同步方法,两个线程,标准打印, 打印? //one  two
 * 2. 新增 Thread.sleep() 给 getOne() ,打印? //one  two
 * 3. 新增普通方法 getThree() , 打印? //three  one   two
 * 4. 两个普通同步方法,两个 Number 对象,打印?  //two  one
* 5. 修改 getOne() 为静态同步方法,打印?  //two   one
* 6. 修改两个方法均为静态同步方法,一个 Number 对象?  //one   two
* 7. 一个静态同步方法,一个非静态同步方法,两个 Number 对象?  //two  one
* 8. 两个静态同步方法,两个 Number 对象?   //one  two
* 
* 线程八锁的关键:
* ①非静态方法的锁默认为  this,  静态方法的锁为 对应的 Class 实例
* ②某一个时刻内,只能有一个线程持有锁,无论几个方法。
*/
public class TestThread8Monitor {

public static void main(String[] args) {
    Number number = new Number();
    Number number2 = new Number();
    
    new Thread(new Runnable() {
        @Override
        public void run() {
            number.getOne();
        } 
    }).start();
    
    new Thread(new Runnable() {
        @Override
        public void run() {
              //number.getTwo();
            number2.getTwo();
        }
    }).start();
    
    /*new Thread(new Runnable() {
        @Override
        public void run() {
            number.getThree();
        }
    }).start();*/
    
}
class Number{

public static synchronized void getOne(){//Number.class
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
    }
    
    System.out.println("one");
}

public synchronized void getTwo(){//this
    System.out.println("two");
}

public void getThree(){
    System.out.println("three");
}

线程八锁的关键:
①非静态方法的锁默认为 this, 静态方法的锁为 对应的 Class 实例
②某一个时刻内,只能有一个线程持有锁,无论几个方法。

相关文章

  • JUC线程高级---读写锁和线程八锁

    **版权声明:本文为小斑马伟原创文章,转载请注明出处! ReadWriteLock 读取操作通常不会改变共享资源,...

  • 可重入读写锁 ReentrantReadWriteLock

    读写锁分为读锁和写锁,多个线程获取读锁不互斥,读写锁、写写锁互斥。 输出

  • java.util.concurrent.locks.Reent

    什么是读写锁 在同一时刻可以允许多个读线程访问,或者写线程访问时,所有的读线程和其他写线程均被阻塞的锁。读写锁一分...

  • Java并发编程基础(五)

    1.读写锁 读写锁在同一个时刻可以拥有多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁...

  • 读写锁

    头文件:#include 读写锁分为读锁和写锁,规则如下: 1,如果某线程申请了读锁,其它线程可以再申请读锁,但不...

  • 2018-07-26 CountDownLatch

    【转】Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例

  • Condition 源码分析 (基于Java 8)

    1. Condition 定义 Condition是JUC里面提供于控制线程释放锁, 然后进行等待其他获取锁的线程...

  • JUC编程:线程池-四大函数式接口-Stream流

    1. 读写锁 ReadWriteLock 独占锁(写锁) 一次只能被一个线程占有 共享锁(读锁) 多个线程可以同时...

  • Condition原理和源码解析

    Condition 定义Condition是JUC里面提供于控制线程释放锁, 然后进行等待其他获取锁的线程发送 s...

  • JUC(十) - 线程八锁

    10. 线程八锁 一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个s...

网友评论

    本文标题:JUC线程高级---读写锁和线程八锁

    本文链接:https://www.haomeiwen.com/subject/ikvxsftx.html