- 浏览: 31545 次
- 性别:
- 来自: 厦门
最新评论
java中可以使用Lock和Synchronized的可以实现对某个共享资源的同步,同时也可以实现对某些过程的原子性操作
Lock可以使用Condition进行线程之间的调度
Synchronized则使用Object对象本身的notify, wait, notityAll调度机制
这两种调度机制有什么异同呢?
Condition是Java5以后出现的机制,它有更好的灵活性,而且在一个对象里面可以有多个Condition(即对象监视器),则线程可以注册在不同的Condition,从而可以有选择性的调度线程,更加灵活。
Synchronized就相当于整个对象只有一个单一的Condition(即该对象本身)所有的线程都注册在它身上,线程调度的时候之后调度所有得注册线程,没有选择权,会出现相当大的问题
下面是一个场景,针对这个场景提出两种解决方案。
一个中转站,可以接纳货物,然后发出货物,这是需要建一个仓库,相当于一个缓冲区,当仓库满的时候,不能接货,仓库空的时候,不能发货。
第一种,用一个Condition去解决,有可能会出问题
第二种解决方案,用java api中的 一个例子
请注意,
(ArrayBlockingQueue 类提供了这项功能,因此没有理由去实现这个示例类。)[size=medium][/size]
Lock可以使用Condition进行线程之间的调度
Synchronized则使用Object对象本身的notify, wait, notityAll调度机制
这两种调度机制有什么异同呢?
Condition是Java5以后出现的机制,它有更好的灵活性,而且在一个对象里面可以有多个Condition(即对象监视器),则线程可以注册在不同的Condition,从而可以有选择性的调度线程,更加灵活。
Synchronized就相当于整个对象只有一个单一的Condition(即该对象本身)所有的线程都注册在它身上,线程调度的时候之后调度所有得注册线程,没有选择权,会出现相当大的问题
下面是一个场景,针对这个场景提出两种解决方案。
一个中转站,可以接纳货物,然后发出货物,这是需要建一个仓库,相当于一个缓冲区,当仓库满的时候,不能接货,仓库空的时候,不能发货。
第一种,用一个Condition去解决,有可能会出问题
package com.zxx; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 单个Condition去控制一个缓冲区,多线程对缓冲区做读写操作,要保证缓冲区满的时侯不会 * 被写,空的时候不会被读;单个Condition控制会出错误: 当缓冲区还有一个位置时,多个写线程 * 同时访问,则只有一个写线程可以对其进行写操作,操作完之后,唤醒在这个condition上等待的 * 其他几个写线程,如果判断用IF语句的话就会出现继续向缓冲区添加。 * @author Administrator * */ public class ConditionError { Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); String[] container = new String[10]; int index = 0; public static void main(String[] args) { ConditionError conditionError = new ConditionError(); conditionError.test(); } public void test(){ ExecutorService threadPool = Executors.newCachedThreadPool(); for(int i = 0; i < 14; i++){//先用14个线程去写,则有4个线程会被阻塞 threadPool.execute(new Runnable(){ @Override public void run() { put(); } }); } Executors.newSingleThreadExecutor().execute(new Runnable(){//用一个线程去取,则会通知4个阻塞的写线程工作,此时 //会有一个线程向缓冲区写,写完后去通知在这个condition上等待 //的取线程,这是它的本意,但是它唤醒了写线程,因为只有一个condition //不能有选择的唤醒写取线程,此时就需要有多个Condition @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } get(); } }); } /** * 向缓冲去写数据 */ public void put(){ lock.lock(); try{ System.out.println(Thread.currentThread().getName() + "当前位置:" + index + "-----------------------------"); while(index == 10){ try { System.out.println(Thread.currentThread().getName() + "处于阻塞状态!"); condition.await(); // index = 0; } catch (InterruptedException e) { e.printStackTrace(); } } container[index] = new String(new Random().nextInt() + ""); condition.signalAll(); index ++; } finally { lock.unlock(); } } /** * 从缓冲区拿数据 */ public void get(){ lock.lock(); try{ while(index == 0){ try { System.out.println("get--------" + Thread.currentThread().getName() + "处于阻塞"); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } index --; System.out.println("get---------" + Thread.currentThread().getName() + "唤醒阻塞"); condition.signalAll(); } finally { lock.unlock(); } } }
第二种解决方案,用java api中的 一个例子
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
请注意,
(ArrayBlockingQueue 类提供了这项功能,因此没有理由去实现这个示例类。)[size=medium][/size]
发表评论
-
装饰模式与代理模式的区别(转载)
2013-04-22 11:28 612学习AOP时,教材上面都说使用的是动态代理,可是在印 ... -
《转》用JPDA轻松调试Java代码
2012-12-05 10:09 669在无法访问运行中的实例时,调试一个Java程序可能相当麻烦;当 ... -
《转》Java入门-高手对 CLASSPATH 的详解
2012-12-05 09:54 0Java入门-高手对 CLASSPATH 的详解 来源: 作者 ... -
《转》再说final变量
2011-11-23 09:36 740再说final变量 分类: 【 ... -
<转>XFire生火指南(下)
2011-11-09 13:44 784<转>XFire生火指南(下) 请先阅读:XFi ... -
myeclipse7.0注册码算法
2011-09-19 21:25 828package com.edj.sessionbean; ... -
(转)cursor 与refcursor及sys_refcursor的区别
2011-09-14 08:56 0(转)cursor 与refcursor及sys_refcur ... -
BigDecimal不整除的一个异常
2011-09-13 09:37 2864BigDecimal不整除的一个异 ... -
(转)由MyEclipse内存不足谈谈JVM内存
2011-09-06 09:07 702原文出处: http://www.javatang.com/a ... -
Property文件的六种读取发放
2011-08-26 16:41 1106Java读取properties文件 【转】 使用J2SE ... -
Eclipse debug 的五个技巧
2011-08-26 16:38 1352Logical Structure The logical s ... -
tomcat端口被占用
2011-08-25 16:02 795关于tomcat端口占用的问题,怎么在myeclipse中启动 ... -
java中标签跳转
2011-08-23 14:02 1020continue语句 1.continue语句用来结束本次 ... -
java一些书籍
2011-08-23 08:56 800深入理解java虚拟机 第二版 深入理解Java虚拟机:JVM ... -
主从表中从主表保存修改的子表
2011-08-22 18:09 1128我们从数据库中查出主表Class,连带它的子表Set<S ... -
java序列化深度克隆
2011-08-18 09:24 784publicObject copy() throwsI ...
相关推荐
Synchronized和java.util.concurrent.locks.Lock都是Java中用于实现线程同步的关键字和接口,它们的主要目标是保证多线程环境下的数据一致性与并发安全。然而,两者在使用方式、控制粒度以及灵活性方面存在显著差异...
在Java中,Lock是一个接口,而synchronized是Java中的关键字,两者都可以用于实现同步锁,但它们有着不同的实现机制和特点。 Java lock同步锁的使用实例解析中,主要介绍了Lock和synchronized两种同步锁机制的异同...
Java中实现同步的方法有多种,如synchronized关键字、Lock接口(如ReentrantLock)以及Semaphore等。 异步编程则允许线程在等待某个操作完成时继续执行其他任务。在异步模型中,调用方法不会立即返回结果,而是通过...
### Java中的同步与异步详解 #### 一、同步机制详解 ##### 1. 同步的基本概念 在Java中,同步是指多个线程在访问共享资源时采取的一种机制,目的是确保同一时间只有一个线程能够访问共享资源。这种机制通过锁...
- **Java线程**:学习如何在Java中创建、启动、停止线程,理解Thread类和Runnable接口。 - **线程同步**:掌握synchronized关键字的用法,包括锁对象、同步代码块和同步方法。 2. **并发控制** - **wait/notify...
在Java中,同步等待队列基于CLH(Craig, Landin, and Hagersten)队列,这是一种高效的双向链表结构。 - **条件等待队列**:通过Condition接口实现,允许线程在满足特定条件时等待,条件满足时再唤醒。Condition...
1. stop() 和 suspend() 方法为何不推荐使用? 2. sleep() 和 wait() 有什么区别? 3. 同步和异步有何异同,...5. 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同? 6. 概括的解释下线程的几种可用状态。
在Java中,线程是程序的执行流,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存。Java提供了两种创建线程的方式:继承Thread类和实现Runnable接口。实例中可能涵盖了这两种方式的使用,并通过...
本文将深入探讨Synchronized关键字锁和ReentrantLock锁的异同、功能特性以及它们在实际应用中的适用场景。 首先,Synchronized是一种内置的Java关键字,它提供了简单而强大的线程同步机制。当一个线程进入一个由...
在Java多线程和高并发领域,面试中常常会涉及到一系列关键问题,这些问题涉及到线程安全、并发控制以及锁机制。以下是对这些问题的详细解答: 1. **stop() 和 suspend() 方法为何不推荐使用?** - `stop()` 方法不...
5. synchronized 和 java.util.concurrent.locks.Lock 的异同 主要相同点:Lock 能完成 synchronized 所实现的所有功能;主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 会自动...
#### 五、简述 `synchronized` 和 `java.util.concurrent.locks.Lock` 的异同? - **相同点**: - `Lock` 接口提供的实现能够完成 `synchronized` 提供的所有功能。 - **不同点**: - `Lock` 提供了更灵活和更...
以上只是部分Java面试中的常见知识点,实际面试中还可能涉及反射、并发编程、Spring框架等更高级的主题。通过深入学习和实践这些知识,将有助于在面试中脱颖而出。而提供的两个PDF文件,"120个Java经典面试题和答案...
- Java中的多线程机制,提高程序的并发执行能力。 #### 8. 文件加密技术 - 使用加密算法保护文件的安全性。 #### 9. 软件开发生命周期 - 包括需求分析、设计、编码、测试和维护等阶段。 #### 10. 路由协议 - ...
1. 接口与抽象类:比较接口和抽象类的异同,理解它们在设计模式中的应用。 2. 多态性:深入理解多态的实现方式和好处,如方法重载和方法覆盖。 3. 泛型:学习泛型的使用,如何限制类型参数,以及泛型通配符。 三、...
- 接口与抽象类:比较接口和抽象类的异同,理解它们在设计中的应用场景。 2. **Java进阶** - 泛型:学习泛型的概念,理解其在代码复用和类型安全上的作用。 - 集合框架:深入研究ArrayList、LinkedList、HashSet...
synchronized和java.util.concurrent.locks.Lock的异同 - **synchronized**:关键字,自动释放锁。 - **Lock**:接口,提供了更高级别的并发控制功能。 #### 48. 如果main方法被声明为private会怎样 - `main`方法...
同时,对Java中并发控制的关键技术synchronized和lock的区别进行了分析。还介绍了CAS无锁机制,乐观锁和悲观锁的概念,原子操作类的应用,以及ABA问题的解释和解决方法。此外,JDK8中并发包的新特性也是这一部分的...
而标签中的"C#"可能表示虽然主要讨论的是Java,但可能也会对比或提及C#的相关知识,例如两种语言在某些特性和设计上的异同。 文件名称"JAVA面试题解惑系列"和"G"可能代表了文件夹或者文档的前缀,具体的面试题和...