`
DiaoCow
  • 浏览: 244187 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java锁相关总结

    博客分类:
  • Java
 
阅读更多
1.ReentrantLock对象
private ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
     //代码段
}
finally {
     lock.unlock();  // 这步至关重要,千万不能遗漏
}

a.一旦一个线程获得了锁对象,那么其他线程都将阻塞在lock.lock()方法中;

b.锁对象是可重入的(即已经获得锁的线程可以再次获得锁),这时候琐计数+1,当线程调用unlock方法时,琐计数-1,只有当琐计数为0时,才被释放;

c.ReentrantLock类还具有一个带有boolean参数的构造方法,该参数表示是否需要执行公平策略,一个公平锁偏爱等待时间最长的线程(会降低性能),默认是随机选择一个线程获得锁;

2.基于锁的条件变量

a.如何创建一个条件变量?
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();

b.如何使用条件变量?
当一个线程获得锁后,发现不具备执行下一步条件时,这时候可以调用condition.await()方法,该方法会导致当前线程释放锁,并且阻塞在当前条件的等待集中;只有当另一个线程调用condition.signalAll()方法或是condition.signal()方法,才能解除阻塞(线程会去重新竞争锁,当再次获得锁后便从await方法返回);

通过条件变量,我们可以简单的实现一个生产者消费者模型(java sdk中代码):
class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newC ondition(); 
   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)  // 一定要是while循环
         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();
     }
   }
 }


c.signal()方法和singalAll()方法的区别:
signalAll方法激活因为该条件而等待的所有线程,而singal只激活其中一个线程;

3.synchronized关键字
a.java中每一个对象都有一个内部锁,如果一个方法用synchronized关键字声明,那么整个方法将被保护起来:
void synchronized method() {
     // 代码片段
}

等价于
void method {
     this.inner.lock(); 
     try {
          // 代码片段
     } finally {
          this.inner.unlock();
     }
}

b.内部对象锁只有一个条件变量,我们可以通过wait方法将线程放入等待集中,也可以通过notif/notifAll方法唤醒等待集中的线程;

c.在静态方法前加synchronized,这时候获得的锁不是对象的内部锁(因为这时候还没对象),获得是当前类字节码锁,所以
public static synchronized void method1 {
}

public static synchronized void method2 {
}

public synchronized void method3 {
}

public synchronized void method4 {
}

method1和method2线程同步,method3和method4线程同步,其余方法之间没有线程同步






1
10
分享到:
评论
7 楼 vavi 2013-03-06  
while (count == items.length)  // 一定要是while循环   
        notFull.await();  

是因为存在 "spurious wakeup"
6 楼 DiaoCow 2012-07-25  
337240552 写道
总结的不错 不过如果是初学者建议看下java编程思想21章 并发 讲的很详细。

谢谢指导 ^_^
5 楼 DiaoCow 2012-07-25  
tenderuser 写道
 while (count == items.length)  // 一定要是while循环  
         notFull.await();  

这个地方为什么一定要用while循环呢? 为什么不直接使用if判断? 在这之前已经获得锁了,已经可以保证对count的独占了(这里只有put和take方法)。。


是这样的,虽然保证count独占了,但是不能保证此时还是满足count==items.length这个条件,打个比方:
首先生产者A线程发现队列已满,然后进入notFull的等待集,这时候消费者B线程从队列中取出一个元素,然后唤醒nutFull等待集中的线程并且释放锁,此时所有线程又开始竞争锁,假设是生产者B线程获得锁,然后向队列中放入一个元素,最后释放锁,此时所有线程又开始竞争锁,终于生产者线程A获得锁,从await方法返回,这时候它必须重新测试下条件是否满足,不然按照我说的流程就会出现问题;
4 楼 337240552 2012-07-25  
总结的不错 不过如果是初学者建议看下java编程思想21章 并发 讲的很详细。
3 楼 DiaoCow 2012-07-25  
railway 写道
总结得还行,不过Java锁并不只这些。
另外,你的notFull、notEmpty变量名我觉得取名full、empty更适合吧。


1.是的,java锁还有其他东西,昨天只温习了这些,所以就先总结了下,其他一定慢慢补上;
2.那段生产者消费者代码,我是摘录java sdk中的代码,一开始我的想法和你一样觉得名字有些别扭,但是后来这么一想,似乎也说的通:当一个生产者需要放入队列时,发现队列已满,这时候它会进入notFull的等待集中,当他收到notFull(队列不满的信号时),它又可以出来活动了; 这只是我说服自己的想法,呵呵
2 楼 railway 2012-07-25  
总结得还行,不过Java锁并不只这些。
另外,你的notFull、notEmpty变量名我觉得取名full、empty更适合吧。
1 楼 tenderuser 2012-07-25  
 while (count == items.length)  // 一定要是while循环  
         notFull.await();  

这个地方为什么一定要用while循环呢? 为什么不直接使用if判断? 在这之前已经获得锁了,已经可以保证对count的独占了(这里只有put和take方法)。。

相关推荐

    java锁详解.pdf

    Java 锁详解 Java 锁是 Java 并发编程中的一种基本机制,用于确保线程安全和避免竞争条件。Java 锁可以分为两大类:synchronized 锁和 ReentrantLock 锁。 一、Synchronized 锁 1. 锁的原理:synchronized 锁是...

    Java锁的种类以及区别

    ### Java锁的种类及其区别 在Java编程语言中,锁是一种重要的同步机制,用于控制多个线程对共享资源的访问,防止数据不一致等问题的发生。本文将详细介绍Java中几种常见的锁类型及其之间的区别。 #### 一、公平锁...

    java锁机制详解.pdf

    总结来说,Java锁机制是通过控制线程对共享资源的访问来保证多线程环境下的数据一致性。`synchronized`提供了一种基础的锁机制,而`Lock`接口则提供了更灵活和强大的功能。理解并正确使用锁机制是编写高效、可靠的...

    Java锁的知识总结及实例代码共7页.pdf.zip

    本资料"Java锁的知识总结及实例代码共7页.pdf.zip"详细介绍了Java锁的原理、类型以及实际应用,旨在帮助开发者深入理解并熟练运用Java锁机制。 在Java中,锁主要分为两类:内置锁(也称为监视器锁)和显式锁。内置...

    Java的锁机制的学习和使用

    #### 一、Java锁机制概览 Java中的锁机制主要用于解决多线程环境下的资源竞争问题。在并发编程中,为了保证数据一致性与正确性,通常需要采用各种锁来控制对共享资源的访问。Java语言提供了多种锁机制,包括`...

    java 锁的类型介绍总结

    java 锁的类型介绍

    java基础知识总结

    同步原语如锁、条件变量等则用于控制并发执行,确保线程安全,避免数据竞争。 4. Java程序可以是Applet或应用程序。Applet嵌入在HTML网页中,而应用程序则独立运行。两者都利用Java的面向对象特性进行设计,但运行...

    java-syn.zip_Java syn_Java syn锁_java同步锁syn_java锁 syn_syn同步事务锁

    4. **Java锁的类型**: - **内置锁**:也称为监视器锁,由`synchronized`关键字提供。 - **显式锁**:如`java.util.concurrent.locks.Lock`接口及其实现,如`ReentrantLock`,提供了更复杂的锁操作,如可中断锁...

    java 并发学习总结

    本学习总结将深入探讨并发容器、同步容器、同步工具、死锁、异常处理、线程中断、线程池、返回结果以及同步方法等核心概念。 1. **并发容器**:Java提供了一系列的并发容器,如`ConcurrentHashMap`,它在并发环境下...

    JAVA多线程总结

    【JAVA多线程总结】 Java 多线程是Java编程中的关键特性,它允许程序同时执行多个任务,提高系统的效率和响应性。本篇总结涵盖了Java多线程的基础概念、创建与启动、线程调度、同步与协作以及新特性。 **一、Java...

    java线程安全总结.doc

    以下是对Java线程安全的深入总结: ### 一、线程安全的定义 线程安全是指当多个线程访问同一块代码时,如果每个线程都能得到预期的结果,且不产生数据不一致或同步问题,那么这块代码就被称为线程安全的。Java中的...

    Java 中的悲观锁和乐观锁的实现

    ### Java中的悲观锁与乐观锁实现详解 #### 一、悲观锁(Pessimistic Locking) 悲观锁是一种基于对数据安全性的保守态度而设计的锁机制。它假设数据在处理过程中很可能被外界修改,因此在整个数据处理过程中都会将...

    java多线程编程总结

    ### Java多线程编程总结 #### 一、Java线程:概念与原理 - **操作系统中线程和进程的概念** 当前的操作系统通常都是多任务操作系统,多线程是一种实现多任务的方式之一。在操作系统层面,进程指的是内存中运行的...

    java分布式锁实现代码

    总结来说,Redisson和Curator都是Java中实现分布式锁的有效工具。选择哪一个取决于具体的需求,如性能、易用性、功能特性以及对底层技术的熟悉程度。在实际项目中,可以根据场景选择合适的方法,确保在分布式环境下...

    一个简单的java类,说明了锁的粒度

    总结来说,Java中的线程同步和锁机制是保证多线程环境下数据一致性的关键工具。锁的粒度是控制同步范围的重要因素,它直接影响程序的并发性能。理解并合理运用这些知识点,对于编写高效、安全的多线程Java程序至关...

    Java多线程编程总结

    ### Java多线程编程总结 #### 一、Java线程:概念与原理 1. **操作系统中线程和进程的概念** - 当前的操作系统通常为多任务操作系统,多线程是实现多任务的一种手段。 - **进程**:指内存中运行的应用程序,每个...

    java多线程的条件对象和锁对象demo

    总结起来,`java多线程的条件对象和锁对象demo`这个例子展示了如何利用`ReentrantLock`和`Condition`来精细控制多线程的执行。它教导我们如何通过条件等待和信号机制实现线程间的协同工作,以及如何利用锁对象来保证...

    Java并发编程技术总结

    Java并发编程技术总结,所含内容有并发特性、并发锁、线程池、并发场景解决方案等,对于性能思考和内容参考资料有一定说明

Global site tag (gtag.js) - Google Analytics