Java多线程的总结与思考

1.防止在共享资源上产生冲突的方式

  • 加锁。使用Synchronized关键字,同步加锁方法,或建立临界区;使用Lock和Atomic类;
  • 根除对变量的共享。使用ThreadLocal类,此类会为每个使用相同变量的每个不同线程都创建不同的存储。即线程本地存储。

2.线程可以驱动任务,那么描述任务的方式和用驱动任务的方式分别有哪些

    描述任务的方式:实现Runnable接口并编写run()方法,但此方法无返回值。如果想要任务完成是能返回一个值,那么可以实现Callable接口并编写call()方法;

    驱动任务的方式:Thread类,传统方式是使用Thread来驱动Runnable对象,即

Thread t = new Thread(new Xxx());
t.start();

其中,Xxx是一个实现了Runnable接口的类。使用Thread的弊端:每个Thread都“注册”了它自己,因此确实有一个对它的引用,而且在它的任务退出其run()并死亡之前,垃圾回收器无法清除它。也就是说,每个Thread进程都会创建一个单独的执行线程,在对start()的调用完成之后,它依旧会继续存在。为避免这个问题,我们使用执行器(Executor)来管理Thread对象,从而简化并发编程。

3.关于线程池ExecutorService

    在说线程池之前,先说执行器(Executor)。ExecutorService实际上是具有服务声明周期的Executor,例如关闭,而Executor则是一个执行线程的工具,它是所有线程池的最顶级的接口。Executor在客户端和任务执行之间提供了一个间接层;与客户端直接执行任务不同,这个中介对象将执行任务。Executor允许你管理异步任务的执行,而无须显示的管理线程的生命周期。

    ExecutorService有三种常用的创建方式,它也是JDK所推崇的三种使用方式。

  • Executors.newCachedThreadPool(),无界线程池,可以自动进行线程回收;
  • Executors.newFixedThreadPool(int),固定大小线程池;
  • Executors.newSingleThreadExecutor(),单一后台线程。

实现代码:

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
可以看到,上面三种创建线程池的方式都是ThreadPoolExecutor类的同一个构造方法不同参数构造的。

4.线程池ThreadPoolExecutor类参数详解

    先看下这个类有几种构造方法:


看源码,前面3个其实都是调用的第4个方法,所以先看看第4个方法的源码实现:

   /**
     * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
     * parameters.
     *
     * @param corePoolSize the number of threads to keep in the
     * pool, even if they are idle.
     * @param maximumPoolSize the maximum number of threads to allow in the
     * pool.
     * @param keepAliveTime when the number of threads is greater than
     * the core, this is the maximum time that excess idle threads
     * will wait for new tasks before terminating.
     * @param unit the time unit for the keepAliveTime
     * argument.
     * @param workQueue the queue to use for holding tasks before they
     * are executed. This queue will hold only the <tt>Runnable</tt>
     * tasks submitted by the <tt>execute</tt> method.
     * @param threadFactory the factory to use when the executor
     * creates a new thread.
     * @param handler the handler to use when execution is blocked
     * because the thread bounds and queue capacities are reached.
     * @throws IllegalArgumentException if corePoolSize or
     * keepAliveTime less than zero, or if maximumPoolSize less than or
     * equal to zero, or if corePoolSize greater than maximumPoolSize.
     * @throws NullPointerException if <tt>workQueue</tt>
     * or <tt>threadFactory</tt> or <tt>handler</tt> are null.
     */
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

总共7个参数,接下来一一介绍:

  • corePoolSize.

  • maximumPoolSize

以上内容主要参考博客 http://blog.csdn.net/ochangwen/article/details/53044733百度一下你就知道




看源码,前面3个其实都是调用的第4个方法,所以先看看第4个方法的参数都是些什么:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值