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

---------------------- 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值