网站程序开发公司北京公司网站设计价格

web/2025/10/5 11:29:58/文章来源:
网站程序开发公司,北京公司网站设计价格,设计师要考什么证,做网站策划书在网上看来很多关于同步锁的博文#xff0c;记录下来方便以后阅读 一、Lock和synchronized有以下几点不同#xff1a; 1#xff09;Lock是一个接口#xff0c;而synchronized是Java中的关键字#xff0c;synchronized是内置的语言实现#xff0c;synchronized是在JVM层面…在网上看来很多关于同步锁的博文记录下来方便以后阅读 一、Lock和synchronized有以下几点不同 1Lock是一个接口而synchronized是Java中的关键字synchronized是内置的语言实现synchronized是在JVM层面上实现的不但可以通过一些监控工具监控synchronized的锁定而且在代码执行时出现异常JVM会自动释放锁定但是使用Lock则不行lock是通过代码实现的要保证锁定一定会被释放就必须将 unLock()放到finally{} 中 2synchronized在发生异常时会自动释放线程占有的锁因此不会导致死锁现象发生而Lock在发生异常时如果没有主动通过unLock()去释放锁则很可能造成死锁现象因此使用Lock时需要在finally块中释放锁 3Lock可以让等待锁的线程响应中断线程可以中断去干别的事务而synchronized却不行使用synchronized时等待的线程会一直等待下去不能够响应中断 4通过Lock可以知道有没有成功获取锁而synchronized却无法办到。 5Lock可以提高多个线程进行读操作的效率。 在性能上来说如果竞争资源不激烈两者的性能是差不多的而当竞争资源非常激烈时即有大量线程同时竞争此时Lock的性能要远远优于synchronized。所以说在具体使用时要根据适当情况选择。 举个例子当有多个线程读写文件时读操作和写操作会发生冲突现象写操作和写操作会发生冲突现象但是读操作和读操作不会发生冲突现象。 但是采用synchronized关键字来实现同步的话就会导致一个问题 如果多个线程都只是进行读操作所以当一个线程在进行读操作时其他线程只能等待无法进行读操作。 因此就需要一种机制来使得多个线程都只是进行读操作时线程之间不会发生冲突通过Lock就可以办到。 另外通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的 二、ReentrantLock获取锁定与三种方式   a) lock(), 如果获取了锁立即返回如果别的线程持有锁当前线程则一直处于休眠状态直到获取锁   b) tryLock(), 如果获取了锁立即返回true如果别的线程正持有锁立即返回false   c)tryLock(long timeout,TimeUnit unit) 如果获取了锁定立即返回true如果别的线程正持有锁会等待参数给定的时间在等待的过程中如果获取了锁定就返回true如果等待超时返回false   d) lockInterruptibly:如果获取了锁定立即返回如果没有获取锁定当前线程处于休眠状态直到或者锁定或者当前线程被别的线程中断 三、下面我们就来探讨一下java.util.concurrent.locks包中常用的类和接口。 1.Lock 首先要说明的就是Lock通过查看Lock的源码可知Lock是一个接口 1 2 3 4 5 6 7 8 public interface Lock {     void lock();     void lockInterruptibly() throws InterruptedException;     boolean tryLock();     boolean tryLock(long time, TimeUnit unit) throws InterruptedException;     void unlock();     Condition newCondition(); } 下面来逐个讲述Lock接口中每个方法的使用lock()、tryLock()、tryLock(long time, TimeUnit unit)和lockInterruptibly()是用来获取锁的。unLock()方法是用来释放锁的。newCondition()这个方法暂且不在此讲述会在后面的线程协作一文中讲述。 在Lock中声明了四个方法来获取锁那么这四个方法有何区别呢 首先lock()方法是平常使用得最多的一个方法就是用来获取锁。如果锁已被其他线程获取则进行等待。 由于在前面讲到如果采用Lock必须主动去释放锁并且在发生异常时不会自动释放锁。因此一般来说使用Lock必须在try{}catch{}块中进行并且将释放锁的操作放在finally块中进行以保证锁一定被被释放防止死锁的发生。通常使用Lock来进行同步的话是以下面这种形式去使用的 1 2 3 4 5 6 7 8 9 Lock lock ...; lock.lock(); try{     //处理任务 }catch(Exception ex){       }finally{     lock.unlock();   //释放锁 } tryLock()方法是有返回值的它表示用来尝试获取锁如果获取成功则返回true如果获取失败即锁已被其他线程获取则返回false也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。 tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的只不过区别在于这个方法在拿不到锁时会等待一定的时间在时间期限之内如果还拿不到锁就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁则返回true。 所以一般情况下通过tryLock来获取锁时是这样使用的 1 2 3 4 5 6 7 8 9 10 11 12 Lock lock ...; if(lock.tryLock()) {      try{          //处理任务      }catch(Exception ex){                }finally{          lock.unlock();   //释放锁      }  }else {     //如果不能获取锁则直接做其他事情 } lockInterruptibly()方法比较特殊当通过这个方法去获取锁时如果线程正在等待获取锁则这个线程能够响应中断即中断线程的等待状态。也就使说当两个线程同时通过lock.lockInterruptibly()想获取某个锁时假若此时线程A获取到了锁而线程B只有在等待那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。 由于lockInterruptibly()的声明中抛出了异常所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException。 因此lockInterruptibly()一般的使用形式如下 1 2 3 4 5 6 7 8 9 public void method() throws InterruptedException {     lock.lockInterruptibly();     try {        //.....     }     finally {         lock.unlock();     }   } 注意当一个线程获取了锁之后是不会被interrupt()方法中断的。因为本身在前面的文章中讲过单独调用interrupt()方法不能中断正在运行过程中的线程只能中断阻塞过程中的线程。 因此当通过lockInterruptibly()方法获取某个锁时如果不能获取到只有进行等待的情况下是可以响应中断的。 而用synchronized修饰的话当一个线程处于等待某个锁的状态是无法被中断的只有一直等待下去。 2.ReentrantLock ReentrantLock意思是“可重入锁”关于可重入锁的概念在下一节讲述。ReentrantLock是唯一实现了Lock接口的类并且ReentrantLock提供了更多的方法。下面通过一些实例看具体看一下如何使用ReentrantLock。 例子1lock()的正确使用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class Test {     private ArrayListInteger arrayList  new ArrayListInteger();     public static void main(String[] args)  {         final Test test  new Test();                   new Thread(){             public void run() {                 test.insert(Thread.currentThread());             };         }.start();                   new Thread(){             public void run() {                 test.insert(Thread.currentThread());             };         }.start();     }             public void insert(Thread thread) {         Lock lock  new ReentrantLock();    //注意这个地方         lock.lock();         try {             System.out.println(thread.getName()得到了锁);             for(int i0;i5;i) {                 arrayList.add(i);             }         } catch (Exception e) {             // TODO: handle exception         }finally {             System.out.println(thread.getName()释放了锁);             lock.unlock();         }     } } 各位朋友先想一下这段代码的输出结果是什么 View Code 也许有朋友会问怎么会输出这个结果第二个线程怎么会在第一个线程释放锁之前得到了锁原因在于在insert方法中的lock变量是局部变量每个线程执行该方法时都会保存一个副本那么理所当然每个线程执行到lock.lock()处获取的是不同的锁所以就不会发生冲突。 知道了原因改起来就比较容易了只需要将lock声明为类的属性即可。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class Test {     private ArrayListInteger arrayList  new ArrayListInteger();     private Lock lock  new ReentrantLock();    //注意这个地方     public static void main(String[] args)  {         final Test test  new Test();                   new Thread(){             public void run() {                 test.insert(Thread.currentThread());             };         }.start();                   new Thread(){             public void run() {                 test.insert(Thread.currentThread());             };         }.start();     }             public void insert(Thread thread) {         lock.lock();         try {             System.out.println(thread.getName()得到了锁);             for(int i0;i5;i) {                 arrayList.add(i);             }         } catch (Exception e) {             // TODO: handle exception         }finally {             System.out.println(thread.getName()释放了锁);             lock.unlock();         }     } } 这样就是正确地使用Lock的方法了。 例子2tryLock()的使用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class Test {     private ArrayListInteger arrayList  new ArrayListInteger();     private Lock lock  new ReentrantLock();    //注意这个地方     public static void main(String[] args)  {         final Test test  new Test();                   new Thread(){             public void run() {                 test.insert(Thread.currentThread());             };         }.start();                   new Thread(){             public void run() {                 test.insert(Thread.currentThread());             };         }.start();     }             public void insert(Thread thread) {         if(lock.tryLock()) {             try {                 System.out.println(thread.getName()得到了锁);                 for(int i0;i5;i) {                     arrayList.add(i);                 }             } catch (Exception e) {                 // TODO: handle exception             }finally {                 System.out.println(thread.getName()释放了锁);                 lock.unlock();             }         } else {             System.out.println(thread.getName()获取锁失败);         }     } } 输出结果 View Code 例子3lockInterruptibly()响应中断的使用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public class Test {     private Lock lock  new ReentrantLock();        public static void main(String[] args)  {         Test test  new Test();         MyThread thread1  new MyThread(test);         MyThread thread2  new MyThread(test);         thread1.start();         thread2.start();                   try {             Thread.sleep(2000);         } catch (InterruptedException e) {             e.printStackTrace();         }         thread2.interrupt();     }             public void insert(Thread thread) throws InterruptedException{         lock.lockInterruptibly();   //注意如果需要正确中断等待锁的线程必须将获取锁放在外面然后将InterruptedException抛出         try {               System.out.println(thread.getName()得到了锁);             long startTime System.currentTimeMillis();             for(    ;     ;) {                 if(System.currentTimeMillis() - startTime Integer.MAX_VALUE)                     break;                 //插入数据             }         }         finally {             System.out.println(Thread.currentThread().getName()执行finally);             lock.unlock();             System.out.println(thread.getName()释放了锁);         }       } }   class MyThread extends Thread {     private Test test  null;     public MyThread(Test test) {         this.test test;     }     Override     public void run() {                   try {             test.insert(Thread.currentThread());         } catch (InterruptedException e) {             System.out.println(Thread.currentThread().getName()被中断);         }     } } 运行之后发现thread2能够被正确中断。 3.ReadWriteLock ReadWriteLock也是一个接口在它里面只定义了两个方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface ReadWriteLock {     /**      * Returns the lock used for reading.      *      * return the lock used for reading.      */     Lock readLock();       /**      * Returns the lock used for writing.      *      * return the lock used for writing.      */     Lock writeLock(); } 一个用来获取读锁一个用来获取写锁。也就是说将文件的读写操作分开分成2个锁来分配给线程从而使得多个线程可以同时进行读操作。下面的ReentrantReadWriteLock实现了ReadWriteLock接口。 4.ReentrantReadWriteLock ReentrantReadWriteLock里面提供了很多丰富的方法不过最主要的有两个方法readLock()和writeLock()用来获取读锁和写锁。 下面通过几个例子来看一下ReentrantReadWriteLock具体用法。 假如有多个线程要同时进行读操作的话先看一下synchronized达到的效果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Test {     private ReentrantReadWriteLock rwl  new ReentrantReadWriteLock();           public static void main(String[] args)  {         final Test test  new Test();                   new Thread(){             public void run() {                 test.get(Thread.currentThread());             };         }.start();                   new Thread(){             public void run() {                 test.get(Thread.currentThread());             };         }.start();               }             public synchronized void get(Thread thread) {         long start System.currentTimeMillis();         while(System.currentTimeMillis() - start  1) {             System.out.println(thread.getName()正在进行读操作);         }         System.out.println(thread.getName()读操作完毕);     } } 这段程序的输出结果会是直到thread1执行完读操作之后才会打印thread2执行读操作的信息。 View Code 而改成用读写锁的话 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class Test {     private ReentrantReadWriteLock rwl  new ReentrantReadWriteLock();           public static void main(String[] args)  {         final Test test  new Test();                   new Thread(){             public void run() {                 test.get(Thread.currentThread());             };         }.start();                   new Thread(){             public void run() {                 test.get(Thread.currentThread());             };         }.start();               }             public void get(Thread thread) {         rwl.readLock().lock();         try {             long start System.currentTimeMillis();                           while(System.currentTimeMillis() - start  1) {                 System.out.println(thread.getName()正在进行读操作);             }             System.out.println(thread.getName()读操作完毕);         } finally {             rwl.readLock().unlock();         }     } } 此时打印的结果为 View Code 说明thread1和thread2在同时进行读操作。 这样就大大提升了读操作的效率。 不过要注意的是如果有一个线程已经占用了读锁则此时其他线程如果要申请写锁则申请写锁的线程会一直等待释放读锁。 如果有一个线程已经占用了写锁则此时其他线程如果申请写锁或者读锁则申请的线程会一直等待释放写锁。 关于ReentrantReadWriteLock类中的其他方法感兴趣的朋友可以自行查阅API文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网店交易平台网站建设青海网站建设公司

集合简介 概念:对象的容器,定义了对多个对象进项操作的的常用方法。可实现数组的功能。和数组的区别: 数组长度固定,集合长度不固定。数组可以存储基本类型和引用类型,集合只能存储引用类型。 位置: jav…

实用设计网站推荐无货源开店已确认违法

我已经开始修改自定义Java二进制运行时映像文件。 映像文件是打包为运行时平台的模块的配置。 基本上,默认映像包含组成Java运行时的所有内容。 自定义图像可以包含该图像的一些子集。 例如,我创建了一个仅包含“ compact 3”概要文件的映像&#xff0c…

国外网站页面做多大不用模板怎么建设网站

接口测试 新增接口脚本编写和执行测试,并执行脚本。 (1)商品单位添加接口描述如下: 接口功能:提供商品单位新增处理。 接口地址(根据实际系统IP及端口自行替换): http://XX.XX.XX.XX:XXXX/prod-api/manager/category/add。 请求方式:POST。 请求参数:

青海建设厅网站通知代理加盟做什么好

课程介绍 学习地址 《Stable Diffusion商业级玩法》通过详细讲解AI绘画技巧、实操演示和个性化指导,帮助您从零基础成为绘画高手,帮助您有效推广产品或服务,提升市场份额。教您掌握稳定扩散绘画技巧,开启艺术创作新篇章。

网站建设方案 doc优秀网站介绍

server {listen 80;server_name example.com;location / {proxy_pass http://backend;}location / 是 Nginx 的一个匹配规则,用于匹配所有请求路径。proxy_pass 指令则用于将匹配到的请求转发给指定的后端服务器。下面是关于 location / 和 proxy_pass 的详细介绍&a…

上海网站备案多久网站ip段屏蔽

很多设计模式看起来或者感觉上差不多,其实不仅仅要从具体的实现方式来辨别,更要主要该种设计模式的意图。 那些容易混淆的设计模式,了解一下~_看了几种设计模式发现有点混乱,都差不多啊-CSDN博客

开一家网站建设公司有前景吗找项目网站

今天,我不得不准备一些示例来说明Web服务是可互操作的。 因此,我已经使用Metro使用Java创建了一个简单的Web服务,并在Tomcat上启动了它。 然后尝试使用Python和Ruby消耗它们。 这是全部完成的过程… Java中的Web服务 我从Java中的简单Web服…

wordpress 基础seo建站东莞在哪里学网站建设

我有个朋友之前在唯品会开的店,现在想转战其他平台,想要店铺信息商品信息全部迁移过去,如果想要人工手动操作就有点麻烦了,然后有天找到我 ,让我看看能不能通过技术手段实现商品信息迁移。嫌来无事,写了下面…

四川微信网站建设推品牌建设归哪个部门管

文章目录 [toc]1. GW1NSR-4C串口外设简介2. FPGA配置3. 常用函数4. 轮询方式接收数据5. 中断方式接收数据 本文是高云FPGA系列教程的第8篇文章。 本篇文章介绍片上ARM Cortex-M3硬核处理器串口外设的使用,演示轮询方式和中断方式接收串口数据,并进行回环…

网站安全设计网站开发前端需要学什么

时代漫画07.PDF: https://url03.ctfile.com/f/1779803-1247458105-0a2c41?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了,截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络!

搭建三合一网站手机网站的内容模块

点击蓝字关注我们C11 中增加了许多的新特性。在本文中,我们来聊一下 lambda 表达式,闭包,std::function以及std::bind。lambda 表达式C11 中新增了 lambda 表达式这一语言特性。lambda 表达式可以让我们快速和便捷的创建一个 “函数”。下面是…

中国国家城乡建设部网站直接用源码做网站盗版吗

写程序员简历时,可以从以下几个方面入手: 1. 个人信息:在简历的开头,包含个人基本信息如姓名、联系方式、地址等。 2. 求职目标/职业目标:明确自己希望得到的职位或行业,并简要描述为什么适合该职位。 3…

济宁梵盛科技网站建设西安做网站的公司

目录 构建生态系统 将Arm架构小芯片带给大众 关于Arm Total Design的结语 我们最近报道了Arm的Neoverse CSS Genesis N2平台的发布,这是一个近乎现成的计算子系统设计,旨在加快尖端基础设施中定制加速器的上市时间。我们当时评论说,我们可…

房产网站关键词优化实验建设网站 南京林业大学

论文基于training-aware NAS和模型缩放得到EfficientNetV2系列,性能远优于目前的模型。另外,为了进一步提升训练速度,论文提出progressive learning训练方法,在训练过程中同时增加输入图片尺寸和正则化强度。从实验结果来看&#…

昆明网站制作服务商wordpress如何设置外网访问

这周没有上课,阅读了《代码大全》第六章模块化设计 内聚性和耦合性 模块化设计的目标是使每个子程序都成为一个“黑盒子”,你知道进入盒子和从盒子里出来 的是什么,却不知道里边发生什么。它的接口非常简单,功能明确,对…

做婚介打么网站好佛山商城网站制作

声明:文章仅用于交流学习,不用于商业项目实施,图片来源于网络,如有侵犯权利,请联系作者及时删除。 本方案旨在对电力电容(PEC和PQM型号)制造工艺深度分析,结合管理要求设计MOM相关功…

娄底北京网站建设建网站引流做淘宝

采集卡默认加载“1 X Full Camera Link”固件,Base模式首先要将固件更新为“2 X Base Camera Link”。 右键SCI图标,选择“打开文件所在的位置”,找到并打开SciDalsaConfig的Demo,如上图所示: 左键单击“获取相机”&a…

电子商务运营网站网店美工的定义

当谈到 Java 网络编程时,经常会听到两个重要的概念:BIO(Blocking I/O,阻塞 I/O)和 NIO(Non-blocking I/O,非阻塞 I/O)。它们都是 Java 中用于处理 I/O 操作的不同编程模型。 一、介…

公司网站建设服务机构广州教育网站建设

const uint8_t usFlashInitVal[] __attribute__((at(0x08002800))) {0x55,0x55,0x55,0x55,0x55};//定位在flash中,0x00030000开始的6个字节信息固定 注意7801的地址在8000000之后 如地址选0x00000800烧录时候报错 不知道是不是atclinktool的bug,使用_…

网站建设设计基础温州营销推广公司

不要做一个清醒的堕落者文章目录 可变参数模板的简介什么是可变参数 模板参数包参数包数据的获取(函数递归获取)参数包的获取(逗号表达式获取) 可变参数的应用emplace 可变参数模板的简介 c11添加的新特性能够让你创建可以接受改变的函数模板和类模板,C98/03&#…