读-写锁 ReadWriteLock & 线程八锁

读-写锁 ReadWriteLock:

①ReadWriteLock 维护了一对相关的锁,一个用于只读操作, 另一个用于写入操作。

   只要没有 writer,读取锁可以由 多个 reader 线程同时保持。写入锁是独占的。。
②ReadWriteLock 读取操作通常不会改变共享资源,但执行 写入操作时,必须独占方式来获取锁。

    对于读取操作占多数的数据结构。 ReadWriteLock 能提供比独占锁更高 的并发性。

    而对于只读的数据结构,其中包含的不变性可以完全不需要考虑加锁操作

TestReadWriteLock

package com.aff.juc;

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

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);// [0-100]随机整数, 100+1 为[1-00]
            }
        }, "一个线程写:").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方法

③ 加个普通方法后发现和同步锁无关

④ 换成两个对象后,不是同一把锁了,情况立刻变化。

⑤ 都换成静态同步方法后,情况又变化

⑥ 所有的非静态同步方法用的都是同一把锁——实例对象本身,

    也就是说如果一个实 例对象的非静态同步方法获取锁后,

    该实 例对象的其他非静态同步方法必须等待获 取锁的方法释放锁后才能获取锁,

    可是别的实例对象的非静态同步方法因为跟该实 例对象的非静态同步方法用的是不同的锁,

    所以毋须等待该实例对象已获取锁的非 静态同步方法释放锁就可以获取他们自己的锁。

⑦ 所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对 象,

     所以静态同步方法与非静态同步方法之间是不会有竞态条件的。但是一旦一个 静态同步方法获取锁后,

     其他静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法

     之间还是不同的实例对象的静态同 步方法之间,只要它们同一个类的实例对象!

关键点:①非静态方法的默认锁为  this,静态方法的默认锁为对应的 Class 实例

              ②某一时刻内,只能有一个线程持有锁,无论几个方法。

猜你喜欢

转载自www.cnblogs.com/afangfang/p/12633146.html