黑马程序员_java基础加强8_多线程加强

原创 2012年03月27日 13:52:19

---------------------- android培训java培训、期待与您交流! ----------------------


5.多个线程访问共享对象和数据的方式

     如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable    

     对象中有那个共享数据。

 

     如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,这时可以将共   

     享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每

     个线程对共享数据的操作方法也分配到那个对象身上去完成(把数据和数据操作封装

     在一起),这样容易实现针对该数据进行的各个操作的互斥和通信。

 

多个线程访问共享对象和数据时,数据容易出现安全问题,因此,要注意加锁。

 

6.线程池的概念:首先创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程池中。

 

在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,若无空闲线程,则任务处于等待状态。记住,任务是提交给整个线程池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

 

Executors工厂类才产生线程池,相关方法(部分)如下:

static ExecutorService newCachedThreadPool()

     创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

static ExecutorService newFixedThreadPool(int nThreads)

     创建一个可重用固定线程数的线程池。

static ScheduledExecutorServicenewScheduledThreadPool(int nThreads)

     创建一个可重用固定线程数的线程池,它可安排在给定延迟后运行或者定期地执行。

static ExecutorService newSingleThreadExecutor()

     创建一个只有一个线程的线程池,相当于newFixedThreadPool(1)

static ScheduledExecutorServicenewSingleThreadScheduledExecutor()

     创建一个单线程的线程池,它可安排在给定延迟后运行或者定期地执行。

 

ExecutorService 常用方法:

void execute(Runnable command)  执行给定的命令,此方法从父接口Executor中继承而来。

void shutdown()

        执行以前提交的任务,但不接受新任务,任务执行完成后池中所有的线程都将死亡。

List<Runnable> shutdownNow()     试图停止所有正在执行的活动任务,暂停处理

                                正在等待的任务,并返回等待执行的任务列表。

<T> Future<T> submit(Callable<T> task)

          提交一个返回值的任务用于执行,返回一个表示任务的结果的Future。

Future<?> submit(Runnable task)      提交一个 Runnable 任务用于执行,并返回一个

          表示该任务的 Future。Future无意义 。

 

Future类中常用方法:

V get()    等待计算完成,然后获取其结果。

V get(long timeout, TimeUnit unit)

          最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

boolean isCancelled()  如果在任务正常完成前将其取消,则返回 true。

boolean isDone()        如果任务已完成,则返回 true。

 

ScheduledExecutorService类继承了ExecutorService接口,常用方法有:

<V> ScheduledFuture<V>  schedule(Callable<V> callable, longdelay, TimeUnit unit)

          创建并执行在给定延迟后启用的ScheduledFuture。

ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit)

          创建并执行在给定延迟后启用的一次性操作。

ScheduledFuture<?> scheduleAtFixedRate(Runnablecommand, long initialDelay, long period, TimeUnit unit)

          创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。

ScheduledFuture<?> scheduleWithFixedDelay(Runnablecommand, long initialDelay, long delay, TimeUnit unit)

          创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。

 

示例:

public class TreadPoolTest {

    public static void main(String[] args) {

        //ExecutorServicepool=Executors.newFixedThreadPool(3);

        //ExecutorServicepool=Executors.newCachedThreadPool();

        ExecutorServicepool=Executors.newSingleThreadExecutor();

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

            final int a=i;

            pool.execute(new Runnable() {

                public void run() {

                   

                    for(int j=0;j<5;j++){

                        try {

                            Thread.currentThread().sleep(500);

                        } catch (InterruptedException e) {

                            e.printStackTrace(); }

            System.out.println("thread:"+a+"  loop:"+j);}}});}

            Future<String>fut=pool.submit(new Callable<String>() {

                public String call()throws Exception {

                System.out.println("call is running……");

                return "hello,java";}});

        System.out.println(fut.get());}}

 

7.CompletionService用于提交一组Callable任务,其take方法返回任务中已完成的一个Callable任务对应的Future对象。

示例:

        ExecutorService service= Executors.newFixedThreadPool(3);

        CompletionService<Integer>completionService =

                   new ExecutorCompletionService<Integer>(service);

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

            completionService.submit(new Callable<Integer>(){

                public Integer call()throws Exception {

                    Integer a = 0;

                    try {

                        a = new Random().nextInt(10);

                        System.out.println("product a:" + a);

 

                        Thread.sleep((long) (a * 100));

                    } catch (Exception e) {

                    }

                    return a;

                }

            });

        }

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

            Future<Integer> f = completionService.take();

            System.out.println("get a:" + f.get());

        }

以上代码基本上遵循返回一个数,得到一个数的趋势。

8.读写锁:

示例:

public class LockTest {

    static Source source=new Source();

    public static void main(String []a){

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

            new Thread(new Runnable() {            

                public void run() {

                    source.setA();}}).start();

            new Thread(new Runnable() {            

                public void run() {

                    source.getA();}}).start();}}}

 

class Source{

    int a=0;

    ReadWriteLock  rwl=new ReentrantReadWriteLock();

    void   setA(){

        rwl.writeLock().lock();

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

" 准备产生a……");

        try {

            Thread.currentThread().sleep(1000);

        } catch (Exception e) {

            e.printStackTrace();}

        a=new Random().nextInt();

        System.out.println(a);

        System.out.println("已经产生a");

        rwl.writeLock().unlock();}

    void  getA(){

        rwl.readLock().lock();

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

" 准备得到a……");

        try {

            Thread.currentThread().sleep(1000);

        } catch (Exception e) {

            e.printStackTrace();}

        System.out.println(a);

        System.out.println("已经得到a");

        rwl.readLock().unlock();}}

通常在释放锁时,代码放在finally中,避免抛出异常时,锁为释放资源。

 

读写锁应用之缓存系统:

public class CacheDemo {

    privateMap<String, Object> cache = new HashMap<String, Object>();

    public staticvoid main(String[] args) {            }

    privateReadWriteLock rwl = new ReentrantReadWriteLock();

    public  Object getData(String key){

        rwl.readLock().lock();

        Object value = null;

        try{

            value= cache.get(key);

            if(value== null){

                rwl.readLock().unlock();

                rwl.writeLock().lock();

                try{

                    if(value==null){

                        value = "aaaa";//实际是去queryDB();

                    }

                }finally{

                    rwl.writeLock().unlock();

                }

                rwl.readLock().lock();

            }

        }finally{

            rwl.readLock().unlock();

        }

        return value;

    }

}






---------------------- android培训java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net/heima

相关文章推荐

黑马程序员----------java基础加强之多线程、单例设计模式

----------------------android培训、java培训、期待与您交流! ---------------------- 虽然老师...

黑马程序员_java基础加强6_多线程加强

---------------------- android培训、java培训、期待与您交流! ---------------------- 1.创建线程的两种方式:  ...

黑马程序员_java基础加强9_多线程加强

---------------------- android培训、java培训、期待与您交流! ---------------------- 8.用Lock实现线程间的通信:...

黑马程序员_java基础加强7_多线程加强

---------------------- android培训、java培训、期待与您交流! ---------------------- 2. 定时器的使用: Ti...

黑马程序员——Java基础--- 多线程

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 1.多线程:java语言提供并发机制,程序员可以在程序中执行多个线程,每个线程完成一个功能,并...

黑马程序员--java基础--多线程

创建线程 继承Thread类 建线程的第一种方式:继承Thread类. 步骤如下: 1 继承Thread类 2 覆写Thread类中的run方法 3 调用线程的start方法,这个方法有两个作用:  ...

黑马程序员---Java基础学习笔记(多线程-前篇)

------------Android培训、Java培训、期待与您交流---------- 1.进程和线程的定义和区别     进程:正在进行的程序。每一个进程执行都有一个执行顺序,该顺序是一个...

黑马程序员——Java基础__多线程(上)

面向对象——多线程(上) 简单概念:任务管理器——进程里面执行的程序里面就有很多的线程,不是同时执行的,只是CPU在做着快速的切换。 什么是API?就是Java用面向对象的思想给程序员封装...

黑马程序员_java基础_多线程

------- android培训、java培训、期待与您交流!--------- 多线程 一、多线程的概述       要理解多线程,就必须理解线程。而要理解线程,就必须知道进程。 ...
  • LFB168
  • LFB168
  • 2015年09月18日 19:22
  • 333

黑马程序员—10—java基础:有关多线程安全的学习笔记和学习心得体会

------- android培训、java培训、期待与您交流! ---------- 1. 通过实例解说多线程安全:    class Ticket implements Runnabl...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:黑马程序员_java基础加强8_多线程加强
举报原因:
原因补充:

(最多只允许输入30个字)