`
jilong-liang
  • 浏览: 481038 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类

Synchronized和java.util.concurrent.locks.Lock的区别

    博客分类:
  • Java
阅读更多


Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。

锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如 ReadWriteLock 的读取锁。

synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。

虽然 synchronized 方法和语句的范围机制使得使用监视器锁编程方便了很多,而且还帮助避免了很多涉及到锁的常见编程错误,但有时也需要以更为灵活的方式使用锁。例如,某些遍历并发访问的数据结果的算法要求使用 "hand-over-hand" 或 "chain locking":获取节点 的锁,然后再获取节点 的锁,然后释放 并获取 C,然后释放 并获取 D,依此类推。Lock 接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,从而支持使用这种技术。

Condition 将 Object 监视器方法(waitnotify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 setwait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其等待)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。

Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。

 

主要相同点:Lock能完成Synchronized所实现的所有功能。

主要不同点:Lock有比Synchronized更精确的县城予以和更好的性能。Synchronized会自动释放锁,但是Lock一定要求程序员手工释放,并且必须在finally从句中释放。

synchronized 修饰方法时 表示同一个对象在不同的线程中 表现为同步队列

如果实例化不同的对象 那么synchronized就不会出现同步效果了。

 

 

1.对象的锁 
所有对象都自动含有单一的锁。 
JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。 
只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁。 
每当任务离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务就可以使用此资源。 
2.synchronized同步块 
2.1同步到单一对象锁 
当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务(线程)只能互斥的进入这些同步块。 
Resource1.java演示了三个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中,虽然这些同步块处在不同的方法中,但由于是同步到同一个对象(当前对象 synchronized (this)),所以对它们的方法依然是互斥的。 

 

package com.org.thread;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

/**

 *@DEMO:JavaSE

 *@Author:jilongliang

 *@Date:2013-3-21

 */

public class Locker {

   public static void main(String[] args) {

        Resources1 res = new Resources1();

        Pro p = new Pro(res);

        Customer1 c = new Customer1(res);

        new Thread(p).start();

        new Thread(c).start();

    }

}

class Pro implements Runnable {

    Resources1 resource;

    Pro(Resources1 res) {

    this.resource = res;

 }

@Override

public void run() {

  while (true) {

  try {

     resource.set("商品");

  } catch (InterruptedException e) {

     e.printStackTrace();

   }

  }

}

}

class Customer1 implements Runnable {

    Resources1 res;

    Customer1(Resources1 res) {

    this.res = res;

}

@Override

public void run() {

  while (true) {

    synchronized (res) {

    try {

      res.out();

   } catch (InterruptedException e) {

     e.printStackTrace();

 }

}

}

}

}

/**

 * wait notify notifyAll 都在使用在同步中,因为要对持有监视器()的线程 操作 所以要使用在同步中,因为只有同步才具有锁

 * 为什么这些操作线程的方法要定义Object类中?

 * 因为这些方法在操作同步中线程时,都必须要标识他们所操作线程只有的锁

 * 只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒 不可以对不同锁中的线程进行唤醒

 * 也就是说,等待和唤醒必须是同一个锁 而锁可以是任意对象,所以可以被任意对象调用的方法定义了

 * Object类中

 */

class Resources1 {

    private String name;

     private int count = 1;

     private boolean flag = false;

     private Lock lock = new ReentrantLock();

     private Condition condition_pro = lock.newCondition();

     private Condition condition_con = lock.newCondition();

     public void set(String name) throws InterruptedException {

     lock.lock();

     try {

          while (flag)

          // this.wait();

          condition_pro.await();// 等待

          this.name = name + "=生产数:" + count++;

          System.out.println(Thread.currentThread().getName() + "生产者:"

          this.name);

          flag = true;

          condition_con.signalAll();

          // this.notifyAll();

          finally {

               lock.unlock();

          }

     }

     public void out() throws InterruptedException {

          lock.lock();

          try {

          while (!flag)

               // this.wait();

               condition_con.await();

               System.out.println(Thread.currentThread().getName()

               "消费者===========" + this.name);

               flag = false;

               condition_pro.signalAll();

               // this.notifyAll();

               finally {

               lock.unlock();

          }

          }

}

 

15
2
分享到:
评论
2 楼 wawxy2009 2013-03-24  
如果对Lock的API进行详细说明就更好了
1 楼 myworld1215 2013-03-22  

相关推荐

    深入Synchronized和java.util.concurrent.locks.Lock的区别详解

    《深入Synchronized与java.util.concurrent.locks.Lock的区别详解》 Synchronized和java.util.concurrent.locks.Lock都是Java中用于实现线程同步的关键字和接口,它们的主要目标是保证多线程环境下的数据一致性与...

    整理的 神舟面试题 笔试题 有答案 要去神舟数码 软件公司面试的注意咯 再一版

    Java 语言的基本知识,包括逻辑操作、条件操作、interface 和 class 的继承、Java Server Page 和 Servlet 的联系和区别、XML 文档定义形式和解析方式、synchronized 和 java.util.concurrent.locks.Lock 的异同、...

    多线程,高并发.pdf

    1. stop() 和 suspend() 方法为何不推荐使用? 2. sleep() 和 wait() 有什么区别? 3. 同步和异步有何异同,...5. 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同? 6. 概括的解释下线程的几种可用状态。

    基于线程池的Java多线程应用技术.pdf

    Java提供了两种方式实现线程同步机制,分别是使用synchronized关键字和java.util.concurrent.locks.Lock接口。 线程池的应用: 线程池技术可以应用于Web服务系统中,控制服务器系统的最大并发数与最多处理的任务数...

    基于Java多线程同步的安全性研究.pdf

    文章首先介绍了Java多线程同步的必要性和重要性,然后讨论了Java多线程同步机制的实现方法,包括使用synchronized关键字和Java.util.concurrent.locks包中的Lock对象。接着,文章讨论了Java多线程同步机制中可能出现...

    工作在同一个java虚拟机中的线程能实现消息互发(alpha)

    6. **管程(Java 5后引入的`java.util.concurrent`包)**:如`java.util.concurrent.locks.Condition`和`java.util.concurrent.CountDownLatch`等,用于协调线程间的协作。 7. **ExecutorService和Future**:`java....

    SimpleDateFormat线程不安全的5种解决方案.docx

    import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SimpleDateFormatExample { private static SimpleDateFormat simpleDateFormat = new ...

    java多线程实现生产者和消费者

    `java.util.concurrent.locks.Condition` 接口与 `java.util.concurrent.locks.Lock` 接口一起使用,提供了比`synchronized`更细粒度的控制。Lock提供了获取和释放锁的方法,而Condition则允许线程等待特定条件并被...

    Java多线程 - (一) 最简单的线程安全问题

    3. **Lock接口**:Java提供`java.util.concurrent.locks.Lock`接口,提供了比`synchronized`更细粒度的锁控制,如可重入锁、公平锁等。例如,`ReentrantLock`。 ```java import java.util.concurrent.locks.Lock; ...

    java多线程编程总结

    - `java.util.concurrent.locks.Lock`接口提供了比`synchronized`更灵活的锁定机制。 #### 六、Java多线程的高级特性 ##### 1. 线程池 - `java.util.concurrent.ExecutorService`接口提供了一种重用固定数量的线程...

    J.U.C系列线程安全的理论讲解编程开发技术共6页.pdf

    3. **`java.util.concurrent.locks`包**:包含锁和条件变量的实现,如`ReentrantLock`、`ReadWriteLock`等,它们提供了比`synchronized`更灵活的锁机制。 4. **`java.util.concurrent.atomic`和`java.util....

    [图文]Java标准类库-.doc

    `synchronized`关键字和`java.util.concurrent.locks`包中的锁机制是实现线程安全的关键。 6. **日期/时间API**:在Java 8之后,`java.time`包取代了传统的`java.util.Date`和`java.util.Calendar`,提供了更加友好...

    java Thread & synchronized & concurrent 线程、同步、并发

    为了解决这一问题,Java提供了更细粒度的锁,如`java.util.concurrent.locks.ReentrantLock`,它具有与`synchronized`相似的功能,但提供了更多的灵活性,如可中断的等待、定时等待和尝试获取锁。 此外,`java.util...

    java的concurrent用法详解

    `java.util.concurrent.locks`包中提供了比`synchronized`关键字更强大、更灵活的锁实现——`ReentrantLock`。 **2.2.1 `ReentrantLock`特性** - 支持公平锁和非公平锁的选择。 - 提供尝试获取锁的能力,可以指定...

    java5 thread

    - `java.util.concurrent.locks`:提供了更灵活的锁定机制,包括`Lock`和`Condition`接口,支持更复杂的线程同步需求。 ### 2. Callable和Future接口 `Callable`接口类似于`Runnable`,但可以返回一个结果,并且...

    concurrent-1.3.4-sources.jar

    4. **java.util.concurrent.locks** 包:这个包提供了高级锁机制,包括ReentrantLock、ReadWriteLock等。ReentrantLock可重入锁比内置的synchronized更灵活,提供了公平性和非公平性选择,以及尝试锁定、定时锁定...

    线程 临界点.rar案例

    在Java中,实现线程临界区的主要工具有synchronized关键字和java.util.concurrent包下的Lock接口(如ReentrantLock)。synchronized是Java内置的同步机制,它可以用于方法或代码块。当synchronized应用于方法时,...

    java中的锁

    内置锁是通过synchronized关键字实现的,而显式锁则是通过java.util.concurrent.locks包中的Lock接口及其实现类来提供的。 一、内置锁(synchronized) 1. 同步方法:在方法声明前加上synchronized关键字,整个...

    JavaLock与Condition的理解Reentran

    ReentrantLock是Java.util.concurrent.locks包下的一个实现,它支持公平锁和非公平锁两种模式。与synchronized不同,ReentrantLock提供了更丰富的功能,如尝试获取锁、可中断等待、定时等待等。其核心特性是可重入性...

    JAVA Concurrent Programming

    4. `java.util.concurrent.locks`包 此包包含各种锁实现,如`ReentrantLock`(可重入锁)、`ReadWriteLock`(读写锁)和`Condition`(条件变量)。这些锁机制提供了更灵活的同步控制,比如读写锁允许多个读线程同时...

Global site tag (gtag.js) - Google Analytics