排他锁和共享锁:

读写锁:既是排他锁,又是共享锁。读锁,共享锁,写锁:排他锁

读和读是不互斥的

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class Demo { private Map<String, Object> map=new HashMap<>();
private ReadWriteLock rwl=new ReentrantReadWriteLock(); private Lock r=rwl.readLock();
private Lock w=rwl.writeLock(); public Object get(String key){
r.lock();
System.out.println(Thread.currentThread().getName()+"读操作正在执行。。。");
try {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return map.get(key);
} finally{
r.unlock();
System.out.println(Thread.currentThread().getId()+"读操作执行完毕。。。");
}
}
public void put(String key,Object value){
w.lock();
System.out.println(Thread.currentThread().getName()+"写操作在执行。。。");
try {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
map.put(key, value);
} finally {
w.unlock();
System.out.println(Thread.currentThread().getName()+"写操作执行完毕。。。");
}
}
}

  

public class Main {
public static void main(String[] args) {
Demo d=new Demo();
d.put("key1", "value1"); // new Thread(new Runnable() {
// @Override
// public void run() {
// d.put("key1", "value1");
// }
// }).start(); new Thread(new Runnable() {
@Override
public void run() {
System.out.println(d.get("key1"));
}
}).start(); new Thread(new Runnable() {
@Override
public void run() {
System.out.println(d.get("key1"));
}
}).start(); new Thread(new Runnable() {
@Override
public void run() {
System.out.println(d.get("key1"));
}
}).start(); // new Thread(new Runnable() {
// @Override
// public void run() {
// d.put("key3", "value3");
// }
// }).start();
}
}

  读写锁需要保存的状态:

写锁重入的次数

读锁的个数

每个读锁重入的次数

锁降级:是指写锁降为读锁  

在写锁没有释放的时候,获取到读锁,在释放写锁

锁升级:

把读锁,升级为写锁

在读锁没有释放的时候,获取到写锁,在释放读锁

private volatile boolean isUpdate;

	public void readWrite(){
r.lock();
if(isUpdate){
r.unlock();
w.lock();
map.put("XXX", "xxx");
r.lock();
w.unlock();
}
Object obj=map.get("XXX");
System.out.println(obj);
r.unlock();
}

  出现线程安全性问题的条件

1.必须在多线程的环境下

2.必须有共享资源

3.对共享资源进行非原子性操作

解决线程安全性问题的途径

1.synchronized 相对慢(偏向锁、轻量级锁、重量级锁)

2.volatile(只能保证读写操作,不能保证非原子性操作)

3.JDK提供的原子类

4.使用Lock(共享锁、排它锁)

认识的“*锁“

1.偏向锁

2.轻量级锁

3.重量级锁

4.重入锁

5.自旋锁

6.共享锁

7.独占锁

8.排它锁

9.读写锁

10.公平锁

11.非公平锁

12.死锁

13.活锁

public class Tmall {
public int count;
public final int MAX_COUNT=10;
public synchronized void push(){
while(count>=MAX_COUNT)
try {
System.out.println(Thread.currentThread().getName()+
"库存数量达到上限,生产者停止生产。");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count++;
System.out.println(Thread.currentThread().getName()
+"生产者生产,当前库存为:"+count);
notify();
}
public synchronized void task(){
while(count<=0)
try {
System.out.println(Thread.currentThread().getName()+
"库存数量为零,消费着等待。");
wait();
} catch (InterruptedException e) { e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+
"消费者消费,当前库存为:"+count);
notify();
}
}

  

public class TaskTarget implements Runnable {
private Tmall tmall;
public TaskTarget(Tmall tmall) {
this.tmall=tmall;
}
@Override
public void run() {
tmall.task();
}
}

  

public class PushTarget implements Runnable{
private Tmall tmall;
public PushTarget(Tmall tmall) {
this.tmall=tmall;
}
@Override
public void run() {
while(true){
tmall.push();
try {
Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace();
}
} }
}

  

public class Main {
public static void main(String[] args){
Tmall tmall=new Tmall();
PushTarget p=new PushTarget(tmall);
TaskTarget t=new TaskTarget(tmall); new Thread(p).start();
new Thread(p).start();
new Thread(p).start(); new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}

  Condition的使用。

public class Demo5 {
private int signal;
//执行顺序 a->b->c
public synchronized void a(){
while(signal!=0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("a");
signal++;
notifyAll();
}
public synchronized void b(){
while(signal!=1){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("b");
signal++;
notifyAll();
}
public synchronized void c(){
while(signal!=2){
try {
wait();
} catch (InterruptedException e) { e.printStackTrace();
}
}
System.out.println("c");
signal=0;
notifyAll();
}
public static void main(String[] args){
Demo5 d=new Demo5();
A a=new A(d);
B b=new B(d);
C c=new C(d); new Thread(a).start();
new Thread(b).start();
new Thread(c).start();
} } class A implements Runnable{
private Demo5 demo;
public A(Demo5 demo){
this.demo=demo;
}
@Override
public void run(){
while(true){
demo.a();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} class B implements Runnable{
private Demo5 demo;
public B(Demo5 demo){
this.demo=demo;
}
@Override
public void run(){
while(true){
demo.b();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} class C implements Runnable{
private Demo5 demo;
public C(Demo5 demo){
this.demo=demo;
}
@Override
public void run(){
while(true){
demo.c();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

  用condition

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Demo { private int signal; Lock lock = new ReentrantLock();
Condition a = lock.newCondition();
Condition b = lock.newCondition();
Condition c = lock.newCondition(); public void a() {
lock.lock();
while(signal != 0 ) {
try {
a.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("a");
signal ++;
b.signal();
lock.unlock();
} public void b() {
lock.lock();
while(signal != 1) {
try {
b.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("b");
signal ++;
c.signal();
lock.unlock();
} public void c () {
lock.lock();
while(signal != 2) {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("c");
signal = 0;
a.signal();
lock.unlock();
} public static void main(String[] args) { Demo d = new Demo();
A a = new A(d);
B b = new B(d);
C c = new C(d); new Thread(a).start();
new Thread(b).start();
new Thread(c).start(); }
} class A implements Runnable { private Demo demo; public A(Demo demo) {
this.demo = demo;
} @Override
public void run() {
while(true) {
demo.a();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
class B implements Runnable { private Demo demo; public B(Demo demo) {
this.demo = demo;
} @Override
public void run() {
while(true) {
demo.b();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
class C implements Runnable { private Demo demo; public C(Demo demo) {
this.demo = demo;
} @Override
public void run() {
while(true) {
demo.c();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

  实现一个队列:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class MyQueue<E> {
private Object[] obj;
private int addIndex;
private int removeIndex;
private int queueSize; private Lock lock=new ReentrantLock();
Condition addCondition=lock.newCondition();
Condition removeCondition=lock.newCondition(); public MyQueue(int count){
obj=new Object[count];
}
public void add(E e){
lock.lock();
//满了之后等待
while(queueSize==obj.length){
try {
addCondition.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
obj[addIndex]=e;
if(++addIndex==obj.length){ //先比较在++
addIndex=0;
}
queueSize++;
removeCondition.signal();
lock.unlock();
}
public void remove(){
lock.lock();
while (queueSize==0) {
try {
removeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
obj[removeIndex]=null;
if(++removeIndex==obj.length){
removeIndex=0;
}
queueSize--;
addCondition.signal();
lock.unlock();
}
}

  

Java线程读写锁的更多相关文章

  1. java多线程-读写锁

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  2. java多线程-读写锁原理

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  3. freeswitch APR库线程读写锁

    概述 freeswitch的核心源代码是基于apr库开发的,在不同的系统上有很好的移植性. 线程读写锁在多线程服务中有重要的作用.对于读数据比写数据频繁的服务,用读写锁代替互斥锁可以提高效率. 由于A ...

  4. 利用Java的读写锁实现缓存的设计

    Java中的读写锁: 多个读锁不互斥, 读锁与写锁互斥, 写锁与写锁互斥, 这是由JVM自行控制的,我们只要上好相应的锁即可. 缓存的设计: package com.cn.gbx; import ja ...

  5. Java 并发 —— 读写锁(ReadWriteLock)

    读写锁(ReadWriteLock),顾名思义,就是在读写某文件时,对该文件上锁. 1. ReentrantReadWriteLock 三部曲: 加锁: 读写操作: 解锁:(为保证解锁操作一定执行,通 ...

  6. Java中读写锁的介绍

    读写锁的简单介绍 所谓的读写锁,就是将一个锁拆分为读锁和写锁两个锁,然后你加锁的时候,可以加读锁,也可以加写锁. ReentrantLock lock=new ReentrantLock(); loc ...

  7. java并发编程-读写锁

    最近项目中需要用到读写锁 读写锁适用于读操作多,写操作少的场景,假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以 ...

  8. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  9. Java线程:概念与原理

    Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...

随机推荐

  1. 【luoguP1414]】又是毕业季II

    题目链接 \(solution\) 暴力求每个数有多少个倍数,从大到小,数\(i\)的倍数有\(f_i\)个,那么选\(1\)~\(f_i\)个同学的答案可以为\(i\),取第一次更新的答案最大 #i ...

  2. GoCN每日新闻(2019-10-25)

    GoCN每日新闻(2019-10-25) GoCN每日新闻(2019-10-25) 1. [译]Golang应付百万级请求/分钟 https://juejin.im/post/5db1464b6fb9 ...

  3. 你对SQA的职责和工作活动(如软件度量)的理解?

    SQA就是独立于软件开发的项目组,通过对软件开发过程的监控,来保证软件的开发流程按照指定的CMM规程(如果有相应的CMM规程),对于不符合项及时提出建议和改进方案,必要时可以向高层经理汇报以求问题的解 ...

  4. mysql 获取学生个人科目平均分

    mysql> select * from test; +----+----------+-------+-----------+ | id | name | score | subject | ...

  5. Java与.net 关于URL Encode 的区别

    在c#中,HttpUtility.UrlEncode("www+mzwu+com")编码结果为www%2bmzwu%2bcom,在和Java开发的平台做对接的时候,对方用用url编 ...

  6. [转]eclipse中explorer显示方式

    原文地址:https://www.cnblogs.com/gne-hwz/p/7590451.html 不知道是不是上面的描述.做个记录 project explorer 项目资源管理器 这个要打开代 ...

  7. 如何连接到远程windows服务器

    在学习和工作中,有些时候我们需要连接到远程服务器,这里,我来演示如何连接到windows服务器. 1. 首先利用快捷键win+r打开运行,或者在搜索框搜索“运行”,然后在运行框输入mstsc,点击确定 ...

  8. openresty开发系列38--通过Lua+Redis 实现动态封禁IP

    openresty开发系列38--通过Lua+Redis 实现动态封禁IP 一)需求背景为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝 ...

  9. C# redis客户端帮助类

    需要在NuGet里面引用ServiceStack.Redis using ServiceStack.Redis; using ServiceStack.Redis.Generic; using Sys ...

  10. WMS开发环境

    须安装以下三个软件: JASPER报表开发工具:TIB_js-studiocomm_6.5.1.final_windows_x86_64.exe UI开发工具:Studio_7.0.0.0_win32 ...