只对同步锁的相关概念做了简单阐述,没给出应用实例。本文,将结合现实中对于同步锁的需求,编个小例子。标题比较大,而实例并不一定十分恰当,请各位见谅。
需求: 一个消费者在不停的从queue里取消息,当没有消息时,阻塞等待,直到有消息来时,消费它。
简析: 乍一看,我们完全可以写个循环不断的去读它(queue),直到该queue不再empty,则消费一条消息(ps: 设个标志位, 循环去读,同理)。可是,无限的循环不仅有可能浪费资源,而且如果额外想设个timeout的话,还要多写好多代码,如需要取当前时间,进行比对等等。这时,如果我们使用wait()或wait(int timeout)让其阻塞等待,直到有其他线程执行了notify(),则可以让问题迎刃而解。
废话不多说,首先是我们的Consumer类。
- import java.util.LinkedList;
- /**
- * Consumer. <BR>
- *
- * @author Michael Ma
- * @version 1.0.0
- */
- public class Consumer {
- /** A lock object */
- private final Object lock;
- /**queue of message */
- private LinkedList<Object> msgQueue = new LinkedList<Object>();
- /** CLOSED message */
- public static final Object CLOSED = new Object();
- /**
- * 构造函数. <BR>
- * lock指向this指针
- *
- */
- public Consumer() {
- this.lock = this;
- }
- /**
- * 开始消费. 如果queue中没有消息,则阻塞 <BR>
- *
- * @return this
- */
- public Consumer startConsume() {
- synchronized (lock) {
- try {
- if (!msgQueue.isEmpty()) {
- return this;
- }
- // 将timeout设为10秒
- lock.wait(10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- return this;
- }
- /**
- * 从queue中读消息 <BR>
- *
- * @return message content
- * @throws Exception e
- */
- public Object getMessage() throws Exception{
- synchronized (lock) {
- // 从queue中取一条消息
- Object message = msgQueue.poll();
- // 若该消息为Error, 抛出
- if (message instanceof Exception) {
- throw (Exception) message;
- }
- // 返回null如果接到CLOSED消息,或message本身为空
- if (message == null
- || message == CLOSED) {
- return null;
- }
- return message;
- }
- }
- /**
- * 向Queue里添加消息, notfify等待中的线程 <BR>
- *
- * @param message Object
- */
- public void setMessage(Object message) {
- synchronized (lock) {
- // 向Queue中添加消息
- msgQueue.add(message);
- // notify等待中的线程
- lock.notify();
- }
- }
- /**
- * 关闭消息 <BR>
- */
- public void setClosed() {
- setMessage(CLOSED);
- }
- }
测试类, 比较简单,就不加注释啦
- public class ConsumerTest extends Thread {
- Consumer c = null;
- public ConsumerTest(Consumer c) {
- this.c = c;
- }
- public static void main(String[] args) throws Exception {
- Consumer c = new Consumer();
- // 开一个线程,去往queue里添加消息
- ConsumerTest test = new ConsumerTest(c);
- test.start();
- Object msg;
- while ((msg = c.startConsume().getMessage()) != null) {
- System.out.println(msg);
- }
- }
- public void run() {
- try {
- sleep(3000);
- c.setMessage(new String("abc"));
- sleep(2000);
- c.setMessage(new String("def"));
- c.setMessage(Consumer.CLOSED);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
小结: 开始编这个例子时,还是挺容犯些小错误的。
1. 首先应该注意synchronized的对象,和wait,notify的对象,是不是相同的, 否则会报llegalMonitorStateException异常。 (解释请参考上文)。
2. 各不同线程操作的对象是不是一个,若notify该类的其他对象则是没用的,当然,如果该类被设计为单体类,就没有这个后顾之忧啦。
3. notifyAll是唤醒在该对象上所有在waiting中的线程,适当场合时应用。(例如一个公告牌,很多线程都在等最新的消息,当公告消息来时,唤醒所有读它的线程。)
相关推荐
文件名`java_demo_synchronized`可能包含的是关于Java同步锁的示例代码,可以从中学习如何在实际项目中应用同步锁策略。通过深入理解同步锁的工作原理和优化技巧,我们可以构建出高效、高并发的Spring Boot应用程序...
### Java同步锁原理 在Java中,`synchronized`关键字用于实现线程同步,即确保同一时刻只有一个线程可以访问特定的代码块或方法。这种机制通过内部维护一个锁来实现,每个对象都有一个内置锁,这个锁可以被任何拥有...
在Java编程中,多线程是...总之,掌握Java的线程同步锁,理解生产者消费者问题及其解决策略,是成为一名合格的Java开发者所必需的技能。通过实际的编程练习,你可以更好地领会这些概念,并运用到实际的并发应用程序中。
Java 同步锁的正确使用方法 Java 同步锁是 Java 编程语言中的一种机制,用于解决多线程环境下的线程安全问题。正确使用同步锁可以确保多线程环境下的数据安全和线程安全。 同步锁的分类 ------------ 同步锁有三...
Spring作为一款广泛使用的Java应用框架,提供了多种方式来实现集群同步锁。本篇文章将深入探讨如何利用Spring在集群环境中实现同步锁,并以Redis作为分布式锁的存储媒介进行实践。 首先,我们要理解什么是集群同步...
"基于Java synchronized同步锁实现线程交互" Java多线程能够提高CPU利用效率,但也容易造成线程不安全、线程死锁等问题。Java synchronized同步锁可以保证同一时刻只有一个线程操作同一资源,使用wait()、notify()...
根据文件内容,本文将主要探讨在Java中应用所谓的“瘦锁(Thin Locks)”技术,以及这种技术在Android Dalvik和ART虚拟机中的应用。 首先,让我们了解瘦锁的概念。在Java中,锁通常用于保证多线程环境下的数据一致...
Java 锁机制 Synchronized 是 Java 语言中的一种同步机制,用于解决多线程并发访问共享资源时可能出现的一些问题。 Java 锁机制 Synchronized 的概念 在 Java 中,每个对象都可以被看作是一个大房子,其中有多个...
Java 锁详解 Java 锁是 Java 并发编程中的一种基本机制,用于确保线程安全和避免竞争条件。Java 锁可以分为两大类:synchronized 锁和 ReentrantLock 锁。 一、Synchronized 锁 1. 锁的原理:synchronized 锁是...
Java中常见的同步锁有synchronized关键字、ReentrantLock(可重入锁)、ReadWriteLock(读写锁)等。synchronized是内置的、隐式的锁,而ReentrantLock和ReadWriteLock属于显式锁,提供了更细粒度的控制和更丰富的...
选择哪种同步锁主要取决于应用场景的需求。如果简单同步即可满足,使用`synchronized`关键字是最简单的选择。对于更复杂的同步需求,如需要更精细的控制、更高的性能或者可中断/定时的等待,Lock接口及其实现更适合...
### Java同步机制浅谈 #### synchronized关键字的作用及应用 在Java多线程环境中,`synchronized`关键字扮演着至关重要的角色。它可以帮助开发者确保多线程环境下的数据一致性,防止因并发访问导致的数据错误。本...
通过这种方式,我们可以轻松地在整个应用中添加Redis同步锁,而无需在每个方法中手动处理锁的获取和释放,提高了代码的可读性和维护性。 此外,还可以考虑以下优化点: - 锁的公平性:默认情况下,Redisson的锁是非...
Java是一种广泛使用的编程语言,它在处理多线程环境下的数据同步和并发控制时,提供了多种锁机制来保证数据的一致性和线程的安全。本文将详细介绍Java中包括乐观锁、悲观锁、自旋锁、可重入锁、读写锁等多种锁机制的...
`synchronized`关键字是最常用的同步机制之一。它可以用来修饰方法或者代码块,确保同一时刻只有一个线程能够访问被修饰的资源。 - **修饰方法**:当`synchronized`用于修饰一个实例方法时,该锁的范围是整个对象;...
Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源时的同步机制。在Java中,当多个线程试图同时访问和修改同一块代码或数据时,可能会导致数据不一致的问题。为了解决这个问题,...
本篇文章将深入探讨Java锁的释放与建立,以及它们之间的_happens-before_关系,旨在帮助开发者更好地理解和应用并发控制。 首先,Java中的锁主要包括两种类型:内置锁(也称为监视器锁)和显式锁。内置锁是通过`...
### Java的锁机制详解 #### 一、Java锁机制概览 Java中的锁机制主要用于解决多线程环境下的资源竞争问题。在并发编程中,为了保证数据一致性与正确性,通常需要采用各种锁来控制对共享资源的访问。Java语言提供了...
锁可以是对象锁、类锁或同步锁。锁的作用是防止多个线程同时访问同一个共享资源,避免资源冲突和数据不一致。 信号量机制是 Java 中的一种线程同步机制。信号量是一个整数值,表示当前可用的资源数量。线程可以通过...
【Java 同步方法】是Java编程中...总之,理解和优化Java同步方法的使用,是提高多线程应用程序性能和可伸缩性的核心。通过精细调整同步策略,可以有效地减少争用,提升并发性能,从而让程序在高负载环境下表现更佳。