多线程(二)

#sleep | wait 关于释放锁和线程的区别

  • sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
  • wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态

#Thread 的问题

  1. new Thread的弊端如下:
  • 每次new Thread新建对象性能差。
  • 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
  • 缺乏更多功能,如定时执行、定期执行、线程中断。
  1. 相比new Thread,Java提供的四种线程池的好处在于:
  • 重用存在的线程,减少对象创建、消亡的开销,性能佳。
  • 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
  • 提供定时执行、定期执行、单线程、并发数控制等功能。

#线程池 ##线程池按以下行为执行任务

  1. 当线程数小于核心线程数时,创建线程。
  2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
  3. 当线程数大于等于核心线程数,且任务队列已满
    • 若线程数小于最大线程数,创建线程
    • 若线程数等于最大线程数,抛出异常,拒绝任务

##Java通过Executors提供四种线程池,分别为:

  • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool 创建一个定时线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序( FIFO, LIFO, 优先级)执行
  • newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。由于线程池无限大,newCachedThreadPool 大家一般不用就是这样的原因,因为它的最大值是在初始化的时候设置为 Integer.MAX_VALUE,一般来说机器都没那么大内存给它不断使用

###newScheduleThreadPool Demo

 public static void testScheduledThreadPool() {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
        for (int i = 0; i < 10; i++) {
            pool.schedule(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(2000);
                        System.out.println(Thread.currentThread().getName() + "is running!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, 3, TimeUnit.SECONDS);
        }
        pool.shutdown();
    }

pool-1-thread-1is running!
pool-1-thread-2is running!
pool-1-thread-1is running!
pool-1-thread-2is running!
pool-1-thread-1is running!
pool-1-thread-2is running!
pool-1-thread-1is running!
pool-1-thread-2is running!
pool-1-thread-1is running!
pool-1-thread-2is running!

Executor.submit() Demo

 public static void testExecutorSubmitMethod() {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        Future<String> future[] = new Future[10];
        for (int i = 0; i < 10; i++) {
            future[i] = pool.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(10);
                    return Thread.currentThread().getName();
                }
            });
        }
        for (Future<String> f : future) {
            try {
                String result = f.get();
                System.out.println(result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        pool.shutdown();
    }
pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2

#Lock | ReadWriteLock 比较好的模板总结:http://blog.youkuaiyun.com/qq_20641565/article/details/53208909

此外,注意搭配!

  • synchronized { wait , notify|notifyAll}
  • Lock {condition.await(), condition.signal()|condition.signalAll()}

#CyclicBarrier 适合执行子任务完了再执行主任务的情况 ##Demo

package BarrierPackage;


import java.util.concurrent.CyclicBarrier;


/**
 * Created by pinker on 17-2-23.
 */
public class CycliCarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier pool=new CyclicBarrier(7,new MainTask());
        for(int i=0;i<7;i++){
            new Thread(new SubTask(pool)).start();
        }
    }

}
package BarrierPackage;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * Created by pinker on 17-2-24.
 */
public class SubTask implements Runnable {
    private CyclicBarrier barrier;

    public SubTask(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);//模仿子任务执行时间!
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "执行完毕,已通知主任务!");
        try {
            barrier.await();//通知障碍器已经完成!
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}
Thread-0执行完毕,已通知主任务!
Thread-1执行完毕,已通知主任务!
Thread-2执行完毕,已通知主任务!
Thread-3执行完毕,已通知主任务!
Thread-4执行完毕,已通知主任务!
Thread-5执行完毕,已通知主任务!
Thread-6执行完毕,已通知主任务!
主任务开始执行了!

转载于:https://my.oschina.net/xd03122049/blog/844647

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值