当前位置: 移动技术网 > IT编程>开发语言>Java > java多线程并发中使用Lockers类将多线程共享资源锁定

java多线程并发中使用Lockers类将多线程共享资源锁定

2019年07月22日  | 移动技术网IT编程  | 我要评论

血刃修罗,黄圣依吻戏视频,大良汽车站

复制代码 代码如下:

package com.yao;

import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.concurrent.future;
import java.util.concurrent.locks.lock;
import java.util.concurrent.locks.readwritelock;
import java.util.concurrent.locks.reentrantlock;
import java.util.concurrent.locks.reentrantreadwritelock;

/**
 * lockers
 * 在多线程编程里面一个重要的概念是锁定,如果一个资源是多个线程共享的,为了保证数据的完整性,
 * 在进行事务性操作时需要将共享资源锁定,这样可以保证在做事务性操作时只有一个线程能对资源进行操作,
 * 从而保证数据的完整性。在5.0以前,锁定的功能是由synchronized关键字来实现的。
 */
public class lockers {

 /**
  * 测试lock的使用。在方法中使用lock,可以避免使用synchronized关键字。
  */
 public static class locktest {

  lock lock = new reentrantlock();// 锁
  double value = 0d; // 值
  int addtimes = 0;

  /**
   * 增加value的值,该方法的操作分为2步,而且相互依赖,必须实现在一个事务中
   * 所以该方法必须同步,以前的做法是在方法声明中使用synchronized关键字。
   */
  public void addvalue(double v) {
   lock.lock();// 取得锁
   system.out.println("locktest to addvalue: " + v + "   "
     + system.currenttimemillis());
   try {
    thread.sleep(1000);
   } catch (interruptedexception e) {
   }
   this.value += v;
   this.addtimes++;
   lock.unlock();// 释放锁
  }

  public double getvalue() {
   return this.value;
  }
 }
 public static void testlocktest() throws exception{
  final locktest locktest = new locktest();
  // 新建任务1,调用locktest的addvalue方法
  runnable task1 = new runnable(){
   public void run(){
    locktest.addvalue(55.55);
   }
  };
  // 新建任务2,调用locktest的getvalue方法
  runnable task2 = new runnable(){
   public void run(){
    system.out.println("value: " + locktest.getvalue());
   }
  };
  // 新建任务执行服务
  executorservice cachedservice = executors.newcachedthreadpool();
  future future = null;
  // 同时执行任务1三次,由于addvalue方法使用了锁机制,所以,实质上会顺序执行
  for (int i=0; i<3; i++){
   future = cachedservice.submit(task1);
  }
  // 等待最后一个任务1被执行完
  future.get();
  // 再执行任务2,输出结果
  future = cachedservice.submit(task2);
  // 等待任务2执行完后,关闭任务执行服务
  future.get();
  cachedservice.shutdownnow();
 }

 /**
  * readwritelock内置两个lock,一个是读的lock,一个是写的lock。
  * 多个线程可同时得到读的lock,但只有一个线程能得到写的lock,
  * 而且写的lock被锁定后,任何线程都不能得到lock。readwritelock提供的方法有:
  * readlock(): 返回一个读的lock
  * writelock(): 返回一个写的lock, 此lock是排他的。
  * readwritelocktest很适合处理类似文件的读写操作。
  * 读的时候可以同时读,但不能写;写的时候既不能同时写也不能读。
  */
 public static class readwritelocktest{
  // 锁
  readwritelock lock = new reentrantreadwritelock();
  // 值
  double value = 0d;
  int addtimes = 0;

  /**
   * 增加value的值,不允许多个线程同时进入该方法
   */
  public void addvalue(double v) {
   // 得到writelock并锁定
   lock writelock = lock.writelock();
   writelock.lock();
   system.out.println("readwritelocktest to addvalue: " + v + "   "
     + system.currenttimemillis());
   try {
    thread.sleep(1000);
   } catch (interruptedexception e) {
   }
   try {
    // 做写的工作
    this.value += v;
    this.addtimes++;
   } finally {
    // 释放writelock锁
    writelock.unlock();
   }
  }
  /**
   * 获得信息。当有线程在调用addvalue方法时,getinfo得到的信息可能是不正确的。
   * 所以,也必须保证该方法在被调用时,没有方法在调用addvalue方法。
   */
  public string getinfo() {
   // 得到readlock并锁定
   lock readlock = lock.readlock();
   readlock.lock();
   system.out.println("readwritelocktest to getinfo   "
     + system.currenttimemillis());
   try {
    thread.sleep(1000);
   } catch (interruptedexception e) {
   }
   try {
    // 做读的工作
    return this.value + " : " + this.addtimes;
   } finally {
    // 释放readlock
    readlock.unlock();
   }
  }
 }

 public static void testreadwritelocktest() throws exception{
  final readwritelocktest readwritelocktest = new readwritelocktest();
  // 新建任务1,调用locktest的addvalue方法
  runnable task_1 = new runnable(){
   public void run(){
    readwritelocktest.addvalue(55.55);
   }
  };
  // 新建任务2,调用locktest的getvalue方法
  runnable task_2 = new runnable(){
   public void run(){
    system.out.println("info: " + readwritelocktest.getinfo());
   }
  };
  // 新建任务执行服务
  executorservice cachedservice_1 = executors.newcachedthreadpool();
  future future_1 = null;
  // 同时执行5个任务,其中前2个任务是task_1,后两个任务是task_2
  for (int i=0; i<2; i++){
   future_1 = cachedservice_1.submit(task_1);
  }
  for (int i=0; i<2; i++){
   future_1 = cachedservice_1.submit(task_2);
  }
  // 最后一个任务是task_1
  future_1 = cachedservice_1.submit(task_1);
  // 这5个任务的执行顺序应该是:
  // 第一个task_1先执行,第二个task_1再执行;这是因为不能同时写,所以必须等。
  // 然后2个task_2同时执行;这是因为在写的时候,就不能读,所以都等待写结束,
  // 又因为可以同时读,所以它们同时执行
  // 最后一个task_1再执行。这是因为在读的时候,也不能写,所以必须等待读结束后,才能写。

  // 等待最后一个task_2被执行完
  future_1.get();
  cachedservice_1.shutdownnow();
 }

 public static void main(string[] args) throws exception{
  lockers.testlocktest();
  system.out.println("---------------------");
  lockers.testreadwritelocktest();
 }
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网