`

Java5.0多线程编程

    博客分类:
  • java
 
阅读更多
[size=large]
Lock接口

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

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

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 来源:www.examda.com
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();

      }     

}

   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();

      }    

}


[/size]
分享到:
评论

相关推荐

    Java 5.0多线程编程

    ### Java 5.0 多线程编程 #### 核心知识点概述 Java 5.0 的发布标志着 Java 在并发编程领域的一个重大突破。在 Java 5.0 之前,多线程编程主要依赖于 `Thread` 类、`Runnable` 接口以及对象的 `wait()`、`notify()...

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

    Java 5.0版本引入了许多重要的新特性和改进,其中就包括对多线程编程的加强。这一进步在Java并发API中得到了体现,尤其是`java.util.concurrent`包的引入,极大地方便了Java并发程序的开发。本文将结合Java 5.0中的...

    Java 5_0 多线程编程实践

    ### Java 5.0 多线程编程实践 在Java 5.0版本中,多线程编程得到了显著增强,特别是在引入了`java.util.concurrent`包之后,为开发者提供了更为丰富的API来处理并发问题。本篇文章将深入探讨如何在Java 5.0中有效地...

    Java API_5.0中文版

    8. **多线程(Multithreading)**:Java API提供了Thread类和Runnable接口来支持多线程编程,理解和掌握线程的同步、互斥、线程池等概念对于开发高并发应用程序至关重要。 9. **I/O流(Input/Output Streams)**:...

    Java 5.0 API 中文版

    10. **并发API的扩展**:包括`java.util.concurrent`包,提供了线程池、并发集合、并发工具类等,极大地改善了多线程编程的体验。 这些新特性极大地提升了Java的生产力和可维护性。通过阅读中文版的Java 5.0 API...

    Java 5.0 Tiger程序高手秘笈.rar

    Java 5.0对并发编程进行了大量优化,包括新增了java.util.concurrent包,提供了线程池、并发容器(如ConcurrentHashMap)以及Future和Callable接口,使得多线程编程更加高效和易于管理。 通过深入学习和实践《Java ...

    Java 5.0 Tiger程序高手秘笈(PDF) Java.rar

    除此之外,书中还可能涉及了Java 5.0中的多线程和并发编程,包括新的并发API如`java.util.concurrent`包,以及线程池、Future和Callable接口等概念。这些内容对于构建高性能、高并发的Web应用至关重要。 总的来说,...

    Java5.0 Tiger程序高手秘笈(含源码)

    9. **并发工具**:Java 5.0引入了`java.util.concurrent`包,提供了线程池、并发容器、同步工具类等,帮助开发者更好地管理多线程和并发编程。 10. **定时器和定时任务**:`java.util.Timer`和`java.util.TimerTask...

    JAVA5.0API

    9. **并发改进**:Java 5.0引入了`java.util.concurrent`包,提供了线程池、Future、Callable等高级并发工具,使得多线程编程更加高效和可控。 10. **NIO.2(New I/O 2.0)**:引入了新的`java.nio.file`包,提供了...

    Java多线程编程实战指南+设计模式篇(全部)

    总之,“Java多线程编程实战指南+设计模式篇(全部)”是一份宝贵的资源,它将帮助读者深入理解Java多线程编程的各个方面,以及如何利用设计模式解决实际问题。学习并掌握这些知识,对于提升Java程序员的专业技能和...

    良葛格java5.0的学习笔记

    10. **Concurrency Updates(并发更新)**:Java 5.0增强了多线程编程的支持,如引入了`java.util.concurrent`包,包含Semaphore、ExecutorService、Future、Callable等类,提供了更高效的线程管理和任务调度。...

    Java多线程-JDK5.0新增线程创建方式

    通过以上两个新增的线程创建方式,我们可以看到Java 5.0版本在多线程编程方面的改进和增强。使用`Callable`接口和线程池不仅提高了线程管理的灵活性,还增强了程序的可扩展性和性能表现。在实际开发过程中,根据具体...

    JAVA 5.0 TIGER程序高手秘笈

    在并发处理方面,Java 5.0引入了并发工具类(java.util.concurrent),如ExecutorService、Future、Semaphore等,这些工具简化了多线程编程,提高了程序的可维护性和性能。还有改进的synchronized关键字,支持基于...

    java 5.0 API 文档 参考册 chm格式

    在并发处理方面,Java 5.0引入了并发工具类(Concurrent Utilities),如ExecutorService、Future、Callable等,这些工具提供了更高级别的并发控制和异步处理能力,使多线程编程更加容易和安全。 除此之外,Java ...

    《Java5.0 Tiger》书籍源码

    《Java 5.0 Tiger》是一本针对Java编程语言5.0版本的权威指南,尤其对Tiger(Java 5.0的代号)引入的新特性进行了深入的讲解。这本书的源码是学习和理解Java 5.0新特性的宝贵资源,包括泛型、枚举、自动装箱与拆箱、...

    Java5.0Tiger程序高手秘笈PDF.rar

    10. **并发改进**:Java 5.0对并发编程提供了大量支持,如`java.util.concurrent`包,包含线程池、并发容器和同步工具类等,提高了多线程编程的效率和安全性。 通过《Java 5.0 Tiger 程序高手秘笈》,读者可以深入...

    Java精华学习资料

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

    javaAPI 5.0中文.rar,javaAPI 5.0中文.rar

    8. **并发工具类(Concurrent Utilities)**:Java 5.0引入了java.util.concurrent包,包含了许多用于多线程编程的工具,如ExecutorService、Semaphore和CyclicBarrier,提高了并发编程的效率和安全性。 9. **枚举...

Global site tag (gtag.js) - Google Analytics