`
jokermanager
  • 浏览: 140504 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java基础--Java 5.0多线程编程(3)

阅读更多

Lock 接口

ReentrantLock Lock 的具体类, Lock 提供了以下一些方法:

  • lock(): 请求锁定,如果锁已被别的线程锁定,调用此方法的线程被阻断进入等待状态。
  • tryLock() :如果锁没被别的线程锁定,进入锁定状态,并返回 true 。若锁已被锁定,返回 false ,不进入等待状态。此方法还可带时间参数,如果锁在方法执行时已被锁定,线程将继续等待规定的时间,若还不行才返回 false
  • unlock() :取消锁定,需要注意的是 Lock 不会自动取消,编程时必须手动解锁。

代码:

// 生成一个锁

Lock lock = new ReentrantLock();

public void accessProtectedResource() {

  lock.lock(); // 取得锁定

  try {

    // 对共享资源进行操作

  } finally {

    // 一定记着把锁取消掉,锁本身是不会自动解锁的

    lock.unlock();

  }

}

ReadWriteLock 接口

   为了提高效率有些共享资源允许同时进行多个读的操作,但只允许一个写的操作,比如一个文件,只要其内容不变可以让多个线程同时读,不必做排他的锁定,排他的锁定只有在写的时候需要,以保证别的线程不会看到数据不完整的文件。 ReadWriteLock 可满足这种需要。 ReadWriteLock 内置两个 Lock ,一个是读的 Lock ,一个是写的 Lock 。多个线程可同时得到读的 Lock ,但只有一个线程能得到写的 Lock ,而且写的 Lock 被锁定后,任何线程都不能得到 Lock ReadWriteLock 提供的方法有:

  • readLock(): 返回一个读的 lock
  • writeLock(): 返回一个写的 lock, lock 是排他的。

ReadWriteLock 的例子:

public class FileOperator{

      // 初始化一个 ReadWriteLock

      ReadWriteLock lock = new ReentrantReadWriteLock();

public String read() {

      // 得到 readLock 并锁定

            Lock readLock = lock.readLock();

             readLock.lock();

            try {

                  // 做读的工作

                  return "Read something";

            } finally {

                 readLock.unlock();

            }

      }

     

public void write(String content) {

      // 得到 writeLock 并锁定

            Lock writeLock = lock.writeLock();

            writeLock.lock();

            try {

                  // 做读的工作

            } finally {

                 writeLock.unlock();

            }

      }

}

 

   需要注意的是 ReadWriteLock 提供了一个高效的锁定机理,但最终程序的运行效率是和程序的设计息息相关的,比如说如果读的线程和写的线程同时在等待,要考虑是先发放读的 lock 还是先发放写的 lock 。如果写发生的频率不高,而且快,可以考虑先给写的 lock 。还要考虑的问题是如果一个写正在等待读完成,此时一个新的读进来,是否要给这个新的读发锁,如果发了,可能导致写的线程等很久。等等此类问题在编程时都要给予充分的考虑。

Condition 接口:

   有时候线程取得 lock 后需要在一定条件下才能做某些工作,比如说经典的 Producer Consumer 问题, Consumer 必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定,等到 Producer 往篮子里放了苹果后再去拿来吃。而 Producer 必须等到篮子空了才能往里放苹果,否则它也需要暂时解锁等 Consumer 把苹果吃了才能往篮子里放苹果。在 Java 5.0 以前,这种功能是由 Object 类的 wait(), notify() notifyAll() 等方法实现的,在 5.0 里面,这些功能集中到了 Condition 这个接口来实现, Condition 提供以下方法:

  • await() :使调用此方法的线程放弃锁定,进入睡眠直到被打断或被唤醒。
  • signal(): 唤醒一个等待的线程
  • signalAll() :唤醒所有等待的线程

Condition 的例子:

public class Basket {     

Lock lock = new ReentrantLock();

// 产生 Condition 对象

     Condition produced = lock.newCondition();

     Condition consumed = lock.newCondition();

     boolean available = false;

     

     public void produce() throws InterruptedException {

           lock.lock();

           try {

                 if(available){

                    consumed.await(); // 放弃 lock 进入睡眠  

                 }

                 /* 生产苹果 */

                 System.out.println("Apple produced.");

                 available = true;

                 produced.signal(); // 发信号唤醒等待这个 Condition 的线程

           } finally {

                 lock.unlock();

           }

     }

    

     public void consume() throws InterruptedException {

           lock.lock();

           try {

                 if(!available){

                       produced.await();// 放弃 lock 进入睡眠  

                 }

                 /* 吃苹果 */

                 System.out.println("Apple consumed.");

                 available = false;

                 consumed.signal();// 发信号唤醒等待这个 Condition 的线程

           } finally {

                 lock.unlock();

           }

     }     

}

ConditionTester:

public class ConditionTester {

     

      public static void main(String[] args) throws InterruptedException{

final Basket basket = new Basket();

// 定义一个 producer

            Runnable producer = new Runnable() {

                  public void run() {

                        try {

                              basket.produce();

                         } catch (InterruptedException ex) {

                              ex.printStackTrace();

                        }

                  }

};

// 定义一个 consumer

            Runnable consumer = new Runnable() {

                  public void run() {

                        try {

                              basket.consume();

                        } catch (InterruptedException ex) {

                              ex.printStackTrace();

                        }

                  }

};

// 各产生 10 consumer producer

            ExecutorService service = Executors.newCachedThreadPool();

            for(int i=0; i < 10; i++)

                  service.submit(consumer);

            Thread.sleep(2000);

            for(int i=0; i<10; i++)

                  service.submit(producer);

            service.shutdown();

      }     

}

5: Synchronizer:同步装置

   Java 5.0 里新加了 4 个协调线程间进程的同步装置,它们分别是 Semaphore, CountDownLatch, CyclicBarrier Exchanger.

Semaphore:

   用来管理一个资源池的工具, Semaphore 可以看成是个通行证,线程要想从资源池拿到资源必须先拿到通行证, Semaphore 提供的通行证数量和资源池的大小一致。如果线程暂时拿不到通行证,线程就会被阻断进入等待状态。以下是一个例子:

public class Pool {

       ArrayList pool = null;

      Semaphore pass = null;

      public Pool(int size){

            // 初始化资源池

            pool = new ArrayList();

            for(int i=0; i

                  pool.add("Resource "+i);

            }

             //Semaphore 的大小和资源池的大小一致

            pass = new Semaphore(size);

      }

      public String get() throws InterruptedException{

            // 获取通行证 , 只有得到通行证后才能得到资源

            pass.acquire();

            return getResource();

      }

      public void put(String resource){

            // 归还通行证,并归还资源

            pass.release();

            releaseResource(resource);

      }

     private synchronized String getResource() {

            String result = pool.get(0);

            pool.remove(0);

            System.out.println("Give out "+result);

            return result;

      }

      private synchronized void releaseResource(String resource) {

            System.out.println("return "+resource);

            pool.add(resource);

      }

}

SemaphoreTest:

public class SemaphoreTest {

      public static void main(String[] args){

            final Pool aPool = new Pool(2);

            Runnable worker = new Runnable() {

                  public void run() {

                        String resource = null;

                         try {

                              // 取得 resource

                              resource = aPool.get();

                        } catch (InterruptedException ex) {

                              ex.printStackTrace();

                        }

                        // resource 做工作

                        System.out.println("I worked on "+resource);

                        // 归还 resource

                        aPool.put(resource);

                  }

            };

            ExecutorService service = Executors.newCachedThreadPool();

            for(int i=0; i<20; i++){

                  service.submit(worker);

            }

            service.shutdown();

      }    

}

 

 

分享到:
评论

相关推荐

    Java5.0多线程编程

    最新Java 5.0多线程编程。

    Java5.0多线程编程实践.pdf

    Java5.0多线程编程实践.pdf

    Java 5.0多线程编程

    java Java多线程 多线程 java Java多线程 多线程 java Java多线程 多线程

    Java高手真经(编程基础卷)光盘全部源码 免积分

    javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip ...

    Java高手真经(编程基础卷)光盘全部源码

    javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip 16....

    (超赞)JAVA精华之--深入JAVA API

    1.7 Java 5.0多线程编程 1.8 Java Socket编程 1.9 Java的内存泄漏 1.10 抽象类与接口的区别 1.11 Java变量类型间的相互转换 2 JAVA与WEB 2.1 JMX规范 2.1.1 JMX概述 2.1.2 设备层(Instrumentation Level) 2.1.3 ...

    多线程编程(电子书)

    Java自1995年面世以来得到了广泛得一个运用,但是对多...在Java 5.0之前Java里的多线程编程主要是通过Thread类,Runnable接口,Object对象中的wait()、 notify()、 notifyAll()等方法和synchronized关键词来实现的。

    精通Java:JDK、数据库系统开发Web开发(实例代码)

    《精通Java:JDK、数据库系统开发Web开发》全书共分27章,内容涵盖了Java编程环境概述、基础语法、面向对象软件设计方法、线程、数据集合、网络编程、图形编程、多媒体编程以及Java Web开发。本书每一节的例子都是...

    java学习笔记 初学者必读

    1. 前言 1-4 1.1. JAVA特点 1-4 1.2. 运行原理 1-4 1.3. JAVA目录 1-4 2. 一•基础知识 2-4 2.1. 配置环境 2-4 2.2. Java中基本概念 2...17.9. JAVA5.0 的注释 (Annotation) 17-73 17.10. Callable 和 Future接口 17-74

    Java精华学习资料

    Java精华学习资料 深入JAVA API 深入理解嵌套类和内部类 文件和流 java中的一些常用词汇 ...Java 5.0多线程编程 Java Socket编程 Java的内存泄漏 抽象类与接口的区别 Java变量类型间的相互转换 ……

    JAVA2核心技术(中文的PDF).part2.rar

    包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK 5.0的内容。本书适合软件开发人员...

    java高手真经 光盘源码

    javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip ...

    Java优化编程(第2版)

    第12章 java多线程技术与应用性能优化 12.1 java多线程技术 12.1.1 进程与线程 12.1.2 线程的生命周期 12.2 并行任务与性能 12.2.1 并行任务与多线程 12.2.2 并行任务与死锁 12.3 线程池技术与应用性能优化 12.3.1 ...

    java+JDK+examples.rar_Swing Examples_java Applet_java file handl

    共有19个章节,169个实例,内容涉及Java的语言基础、面向对象程序设计、数字处理、数组与集合、字符串、异常处理、文件操作、多线程、Swing编程、图形和多媒体编程、反射机制、网络程序设计、数据库编程、Applet、...

    JAVA2核心技术(中文的PDF).part1.rar

    包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK 5.0的内容。本书适合软件开发人员...

Global site tag (gtag.js) - Google Analytics