当前位置:   article > 正文

多线程(三):锁(Lock) 读写锁()ReadWriteLock (synchronized)_cache 读写对象锁

cache 读写对象锁

//Lock 锁的例子:和synchronized效果类似。

  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class LockTest8 {
  4. //Lock用来代替synchronized。
  5. public static void main(String[] args) {
  6. //(用两个线程)实现向屏幕打印两个字符串,tom jerry。
  7. new LockTest8().init();
  8. //多线程代码块中(run方法内)要做到互斥效果,需要用到同一个对象锁.
  9. }
  10. /**
  11. * 打印字符类
  12. */
  13. class OutPutToScreen{
  14. //产生一把锁.
  15. Lock lock = new ReentrantLock();
  16. public void print(String string){
  17. //锁住
  18. lock.lock();
  19. try {
  20. int len = string.length();
  21. for(int i=0;i<len;i++){
  22. System.out.print(string.charAt(i));
  23. }
  24. System.out.println();
  25. }finally{
  26. //解锁
  27. //unlock放在finally里比较好。以防发生异常时候没有释放锁.
  28. lock.unlock();
  29. }
  30. }
  31. }
  32. /**
  33. * run方法里面操作的是同一个对象。因此用到当前对象锁,当前对象在被线程占用时,其他线程无法操作。
  34. */
  35. public void init(){
  36. OutPutToScreen print = new OutPutToScreen();
  37. new Thread(new Runnable() {
  38. @Override
  39. public void run() {
  40. while (true) {
  41. print.print("thread_test");
  42. }
  43. }
  44. }).start();
  45. new Thread(new Runnable() {
  46. @Override
  47. public void run() {
  48. while (true) {
  49. print.print("tom_and_jerry");
  50. }
  51. }
  52. }).start();
  53. }
  54. }

  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class LockTest8_1 {
  4. public static void main(String[] args) {
  5. //(用两个线程)实现向屏幕打印两个字符串,tom jerry。
  6. new LockTest8_1().init();
  7. }
  8. Lock lock = new ReentrantLock();
  9. /**
  10. * 打印字符类
  11. */
  12. class OutPutToScreen{
  13. //互斥效果一定要是同一个对象,这个例子中A线程用到OutPutToScreen print对象,B
  14. public void print(String string){
  15. lockTest(string);
  16. }
  17. public void print2(String string){
  18. lockTest(string);
  19. }
  20. public void lockTest(String string){
  21. lock.lock();
  22. try {
  23. int len = string.length();
  24. for(int i=0;i<len;i++){
  25. System.out.print(string.charAt(i));
  26. }
  27. System.out.println();
  28. } finally{
  29. lock.unlock();
  30. }
  31. }
  32. }
  33. public void init(){
  34. OutPutToScreen print = new OutPutToScreen();
  35. OutPutToScreen print2 = new OutPutToScreen();
  36. new Thread(new Runnable() {
  37. @Override
  38. public void run() {
  39. while (true) {
  40. //线程操作不同对象
  41. print.print("thread_test");
  42. }
  43. }
  44. }).start();
  45. new Thread(new Runnable() {
  46. @Override
  47. public void run() {
  48. while (true) {
  49. //线程操作不同对象
  50. print2.print("tom_and_jerry");
  51. }
  52. }
  53. }).start();
  54. }
  55. }

// 读写锁。的例子介绍

  1. import java.util.Map;
  2. import java.util.TreeMap;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReadWriteLock;
  5. import java.util.concurrent.locks.ReentrantReadWriteLock;
  6. import javax.xml.crypto.Data;
  7. public class LockReadWriteTest {
  8. public static void main(String[] args) {
  9. //读写锁测试。读和写要互斥,读和读不用互斥,写和写要互斥,这个是基本的规则
  10. //共享数据封装在一个类中。
  11. LockReadWriteTest test = new LockReadWriteTest();
  12. test.test();
  13. }
  14. public void test(){
  15. MyData data = new MyData();
  16. Random r =new Random();
  17. //3个线程负责读
  18. for(int i=0;i<3;i++){
  19. new Thread(new Runnable() {
  20. @Override
  21. public void run() {
  22. while(true){
  23. data.read();
  24. }
  25. }
  26. }).start();
  27. }
  28. //3个线程负责写
  29. for(int i=0;i<3;i++){
  30. new Thread(new Runnable() {
  31. @Override
  32. public void run() {
  33. while(true){
  34. data.write(r.nextInt(1000));
  35. }
  36. }
  37. }).start();
  38. }
  39. }
  40. class MyData{
  41. //读写锁:读和写操作互斥。
  42. ReadWriteLock lock = new ReentrantReadWriteLock();
  43. private Object data = null;
  44. //读
  45. public void read() {
  46. //
  47. lock.readLock().lock();
  48. try {
  49. System.out.println("准备读...");
  50. Thread.sleep(100);
  51. System.out.println("读取完毕:"+this.data);
  52. }catch (InterruptedException e) {
  53. e.printStackTrace();
  54. }finally{
  55. lock.readLock().unlock();
  56. }
  57. }
  58. //写
  59. public void write(int data){
  60. lock.writeLock().lock();
  61. try {
  62. System.out.println("准备写...");
  63. Thread.sleep(100);
  64. this.data = data;
  65. System.out.println("写入完毕:"+this.data);
  66. }catch (InterruptedException e) {
  67. e.printStackTrace();
  68. } finally{
  69. lock.writeLock().unlock();
  70. }
  71. }
  72. }
}

//读写锁API中的例子

  1. class CachedData {
  2. Object data;//缓存数据
  3. volatile boolean cacheValid;//缓存是否存在
  4. //读写锁
  5. final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  6. //阅读这段代码时先考虑缓存常用的操作,那就是频繁读取,其次处理写入操作。
  7. //并发的时候多个线程读的话不会造成数据的破坏,所以先上读锁,如果没有数据可读,就会有一个线程开始写入数据,
  8. //并且给上 上写锁,在写之中不能读。写完了以后还原为读锁。这样读和写之间可以到达互斥效果。
  9. void processCachedData() {
  10. //0 读锁:当读取缓存数据时,不能有写入操作。
  11. rwl.readLock().lock();
  12. //3当没有缓存时候,就是写入缓存操作了
  13. if (!cacheValid) {
  14. // Must release read lock before acquiring write lock
  15. //4在写入前先释放读锁。
  16. rwl.readLock().unlock();
  17. //5接着在写入时候上 写锁
  18. rwl.writeLock().lock();
  19. try {
  20. // Recheck state because another thread might have
  21. // acquired write lock and changed state before we did.
  22. //6在写之前再次判断一下是否写入数据或者更改数据了。因为还有可能有线程拿到写锁.
  23. if (!cacheValid) {
  24. //7写入数据
  25. data = ...
  26. //8更改标记位
  27. cacheValid = true;
  28. }
  29. // Downgrade by acquiring read lock before releasing write lock
  30. //9在写入操作最后 在上 上读锁
  31. rwl.readLock().lock();
  32. } finally {
  33. //10在写入操作最后释放写锁
  34. rwl.writeLock().unlock(); // Unlock write, still hold read
  35. }
  36. }
  37. try {
  38. //1 读取数据即可
  39. use(data);
  40. } finally {
  41. //2 最后释放读锁
  42. rwl.readLock().unlock();
  43. }
  44. }
  45. }}


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/956057
推荐阅读
相关标签
  

闽ICP备14008679号