java 实现共享锁和排它锁
一直对多线程有恐惧,在实现共享锁和排它锁之后,感觉好了很多。
共享锁 就是查询的时候,如果没有修改,可以支持多线程查询;
排它锁 就是修改的时候,锁定共享锁,停止查询,同时,锁定排它锁,只允许一个线程进行修改,修改完成后,再解开共享锁;
心路历程: 一开始的想法是,绝对不调用 sleep ,要用到sleep 的地方我觉得都可以用 notify() 和 wait() 替换,sleep(T) 我觉得T 的大小压根是无法算出来的,如果非要用sleep 我觉得T 的时间应该是一个动态的值,这个值是通过函数的执行时间的一个平均值(每N次执行算一个 平均值出来) 但个人觉得还是不如notify() 和wait(); 我为了简单,操作的是一颗字典树代替B树;如何实现读支持多线程,写单线程呢! 当各种查询和修改的操作以多线程的方式提交给线程池的时候,程序会从阻塞队列里面不断的取任务,当前面取到的任务是 查询的时候,不要管他,没有修改表结构,直接丢给一个线程,当取到的下任务是一个修改或者更新的任务时,首先必须等待前面的查询全部查询完,然后再停掉阻塞队列不断的添加任务, 要让我修改完成之后,再唤醒阻塞队列添加任务;由于我不知道如何停掉线程池的阻塞队列添加任务,所以干脆自己模拟线程池这个过程;(理论上这个方法是可行的) 主要的卡是在notify() 和 wait()的理解上面,这两个方法执行时都必须在 锁里面; 所以在查询的代码里面,你不能wait() 那样会变成单线程;
1 insert; 2 remove; 3 query; -1 stopRun
package com.trafree; import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger; /**
* Created by on_the_way on 2014/12/31.
*/
public class AboutThread { public static boolean insert(String str) {
int len = str.length();
Trie p = root;
for (int i = 0; i < len; i++) {
int num = str.charAt(i) - 'a';
if (p.next[num] == null) {
p.next[num] = new Trie();
}
p = p.next[num];
}
if (p.end) return false;
return p.end = true;
} public static boolean remove(String str) {
int len = str.length();
Trie p = root;
for (int i = 0; i < len; i++) {
int num = str.charAt(i) - 'a';
if (p.next[num] == null) {
return false;
}
p = p.next[num];
}
if (!p.end) {
return false;
}
p.end = false;
return true;
} public static boolean query(String str) {
int len = str.length();
Trie p = root;
for (int i = 0; i < len; i++) {
int num = str.charAt(i) - 'a';
if (p.next[num] == null) {
return false;
}
p = p.next[num];
}
return p.end;
} public static Trie root = new Trie(); public static class Trie {
public Trie next[] = new Trie[26];
public boolean end; public Trie() {
for (int i = 0; i < 26; i++) {
this.next[i] = null;
}
this.end = false;
}
} public static class Consumer implements Runnable {
public void run() {
try {
MyThread.process();
} catch (Exception e) {
e.printStackTrace();
}
}
} public static class MyThread implements Runnable { public int sequence;
public int action;
public String str;
public boolean res; public static Object lock1 = new Object();
public static Object lock2 = new Object();
public static Object lock3 = new Object(); public static boolean needNotify1 = false;
public static boolean needNotify2 = false;
public static boolean needNotify3 = false;
public static boolean runModify = false; public static AtomicInteger queryNum = new AtomicInteger(0);
public static Queue<MyThread> pool = new LinkedList<MyThread>(); public MyThread(int sequence, int action, String str) {
this.sequence = sequence;
this.action = action;
this.str = str;
this.res = false;
} public static void process() throws InterruptedException { boolean needBreak = false;
while (true) {
if( pool.size() == 0 && needBreak ){
break;
}
synchronized (lock1) {
if (pool.size() == 0) {
needNotify1 = true;
lock1.wait();
}
}
synchronized (lock3) {
if (runModify) {
needNotify3 = true;
lock3.wait();
}
}
MyThread myThread = pool.poll(); if (myThread.action == -1){
needBreak = true;continue;
}
if (myThread.action == 1 || myThread.action == 2) {
synchronized (lock2) {
if (queryNum.get() != 0) {
needNotify2 = true;
runModify = true;
lock2.wait();
new Thread(myThread).start();
} else {
runModify = true;
new Thread(myThread).start();
}
}
} else {
queryNum.incrementAndGet();
new Thread(myThread).start();
}
}
} public void run() {
if (this.action == 1) {
this.res = insert(this.str);
synchronized (lock3) {
needNotify1 = false;
runModify = false;
if( needNotify3 )lock3.notify();
}
System.out.println(sequence+" "+action+" "+str+" "+res);
} else if (this.action == 2) {
this.res = remove(this.str);
synchronized (lock3) {
needNotify1 = false;
runModify = false;
if( needNotify3 )lock3.notify();
}
System.out.println(sequence+" "+action+" " + str+" "+res);
} else {
this.res = query(str);
System.out.println(sequence+" "+action+" "+str+" "+res);
synchronized (lock2) {
if (queryNum.decrementAndGet() == 0 ) {
if(needNotify2)lock2.notify();
}
}
}
} } public static void main(String arg[]) throws IOException { File file = new File("F:" + File.separator + "in.txt");
Scanner cin = new Scanner(file);
int N = cin.nextInt();
int M = cin.nextInt(); for (int i = 0; i < N; i++) {
insert(cin.next());
} new Thread(new Consumer()).start();
for (int i = 0; i < M; i++) {
MyThread myThread = new MyThread(i, cin.nextInt(), cin.next());
synchronized (MyThread.lock1) {
MyThread.pool.add(myThread);
if (MyThread.needNotify1) {
MyThread.needNotify1 = false;
MyThread.lock1.notify();
}
}
}
}
}
40 45
what
make
you
so
beautiful
have
think
cell
green
red
java
hand
forum
discuss
online
contests
teaching
exercise
contest
recent
icpc
authors
ranklist
problem
achive
exams
university
judge
register
new
fortunately
old
behind
locked
the
feature
find
by
alphabet
more
3 what
3 more
3 old
3 find
3 exams
3 achive
3 icpc
3 recent
3 ranklist
2 ranklist
3 ranklist
1 ranklist
3 ranklist
3 find
3 alphabet
2 find
2 find
3 find
2 alphabet
1 alphabet
3 alphabet
3 find
1 find
3 find
3 what
3 more
3 old
3 find
3 exams
3 achive
3 icpc
3 recent
3 ranklist
3 ranklist
3 what
3 more
3 old
3 find
3 exams
3 achive
3 icpc
3 recent
3 ranklist
3 ranklist
-1 end
java 实现共享锁和排它锁的更多相关文章
- 对mysql乐观锁、悲观锁、共享锁、排它锁、行锁、表锁概念的理解
乐观锁 乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了. 实现: 通常实现是 ...
- MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解
文章出处:https://www.souyunku.com/2018/07/30/mysql/?utm_source=tuicool&utm_medium=referral MySQL/Inn ...
- C# 乐观锁、悲观锁、共享锁、排它锁、互斥锁
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据 ...
- mysql 乐观锁、悲观锁、共享锁,排它锁
mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...
- MySql共享锁和排它锁
共享锁和排他锁 1.共享锁: 读锁.X锁,在查询时生效,多个事务在查询同一个数据时共享一把锁,但是不能作用于修改数据,在select语句后添加 lock in share mode : 2.排他锁:在 ...
- mysql 开发进阶篇系列 8 锁问题 (共享锁与排它锁演示)
1 .innodb 共享锁(lock in share mode)演示 会话1 会话2 SET autocommit=0; SELECT cityname FROM city WHERE city_ ...
- mysql共享锁与排它锁
共享锁shared lock(也叫读锁read lock)又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁.这保证了其 ...
- Java锁--共享锁和ReentrantReadWriteLock
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3505809.html ReadWriteLock 和 ReentrantReadWriteLock介绍 ...
- MySQL锁之三:MySQL的共享锁与排它锁编码演示
一.行锁之MySQL 使用SELECT ... FOR UPDATE 做事务写入前的确认 以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEA ...
随机推荐
- WinCE数据通讯之Web Service篇
准备写个WinCE平台与数据库服务器数据通讯交互方面的专题文章,今天先整理个Web Service通讯方式. 公司目前的硬件产品平台是WinCE5.0,数据通讯是连接服务器与终端的桥梁,关系着终端的数 ...
- Outlook 配置qq邮箱账号
最近想用Outlook 2013管理QQ邮件,配置好久都没有成功,结果最后发现第三方登陆QQ邮箱不使用QQ密码,而是使用一个叫”授权码”的东西.(用户名自动生成的,授权码就填这,报错后填会测试不通过) ...
- 【性能测试】服务器性能监控、数据采集工具nmon安装使用详解
nmon nmon是一种在AIX与各种Linux操作系统上广泛使用的监控与分析工具,它能在系统运行过程中实时地捕捉系统资源的使用情况,并且能输出结果到文件中,然后通过nmon_analyzer工具产生 ...
- JavaScript权威指南--语句
知识要点 在javascript中,表达式是短语,那么语句(statement)就是整句或命令.表达式计算出一个值,但语句用来执行以使某件事发生. 1.表达式语句 具有副作用的表达式是JavaScri ...
- JavaScript Browser 对象 实例
使用JavaScript来访问和控制浏览器对象实例. Window 对象 弹出一个警告框 弹出一个带折行的警告框 弹出一个确认框,并提醒访客点击的内容 弹出一个提示框 点击一个按钮时,打开一个新窗口 ...
- SpringBoot下的值注入
在我们实际开发项目中,经常会遇到一些常量的配置,比如url,暂时不会改变的字段参数,这个时候我们最好是不要直接写死在代码里的,因为这样编写的程序,应用扩展性太差了,我们可以直接写在配置文件中然后通过配 ...
- C#/Java 程序员转GO/golang程序员笔记大全(day 01)
前言: 整理一下学习 Go 语言的笔记,作为一名老程序,学习一名新的开发语言自然不需要像小白那样从 HelloWorld 看起. 简单整理一下 Go 的一些差异处,希望对大家学习 go 有点帮助,不正 ...
- 一款连接SqlServer的数据库工具
由于自己使用的电脑系统是xp,而服务器上的数据库是SqlServer2012,于是用SqlServer2005管理端操作2012,总是不成功.在网上也百度谷歌了很久,也没有解决,也发了很多问没有找到解 ...
- C++复习1.内存管理的知识
C++ 内存管理 1.内存分配的方式有三种: 从静态存储区分配:在程序编译期间已经分配好了,这些在程序的生命周期内都是有效的,如全局变量,static变量 一个例子: char * p = " ...
- 【WebGL】2.基础概念
引入Three.js <!DOCTYPE html> <html> <head> <title></title> </head> ...