码迷,mamicode.com
首页 > 编程语言 > 详细

多线程

时间:2017-02-27 19:37:28      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:实例   block   second   同步阻塞   执行   机器   请求   队列   自己的   

多线程概念:指的是这个程序(一个进程)运行时产生了不止一个线程

一、多线程的实现方式

  • 继承Thread
  • 实现Runable接口

二、多线程并行与并发

  • 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
  • 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。
  • 线程安全:经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可
  • 同步:Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。如代码简单加入@synchronized关键字。在保证结果准确的同时,提高性能,才是优秀的程序。线程安全的优先级高于性能。

三、线程状态

    1. 新建状态(New):新创建了一个线程对象。
    2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
    3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
    4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
        (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
        (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
        (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
    5. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

         关于中断:它并不像stop方法那样会中断一个正在运行的线程。线程会不时地检测中断标识位,以判断线程是否应该被中断(中断标识值是否为true)。终端只会影响到wait状态、sleep状态和join状态。被打断的线程会抛出InterruptedException。
         Thread.interrupted()检查当前线程是否发生中断,返回boolean
         synchronized在获锁的过程中是不能被中断的。

         如何获取线程中的异常

         不能用try,catch来获取线程中的异常
 
四、高级多线程控制类
  • TreadLocal

    用处:保存线程的独立变量。
    当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。常用于用户登录控制,如记录session信息。

    实现:每个Thread都持有一个TreadLocalMap类型的变量(该类是一个轻量级的Map,功能与map一样,区别是桶里放的是entry而不是entry的链表。功能还是一个map。)以本身为key,以目标为value。
    主要方法是get()和set(T a),set之后在map里维护一个threadLocal -> a,get时将a返回。ThreadLocal是一个特殊的容器。

  • 原子类
  • Lock类

            lock更灵活,可以自由定义多把锁的枷锁解锁顺序(synchronized要按照先加的后解顺序)提供多种加锁方案,lock 阻塞式, trylock 无阻塞式, lockInterruptily 可打断式, 还有trylock的带超时时间版本。

            本质上和监视器锁(即synchronized是一样的)能力越大,责任越大,必须控制好加锁和解锁,否则会导致灾难。和Condition类的结合。

          ReentrantLock    
             可重入的意义在于持有锁的线程可以继续持有,并且要释放对等的次数后才真正释放该锁。

  • 容器类

         BlockingQueue
    阻塞队列。该类是java.util.concurrent包下的重要类,通过对Queue的学习可以得知,这个queue是单向队列,可以在队列头添加元素和在队尾删除或取出元素。类似于一个管  道,特别适用于先进先出策略的一些应用场景。普通的queue接口主要实现有              PriorityQueue(优先队列)此外,

           常见的阻塞队列还有:ArrayListBlockingQueue、 LinkedListBlockingQueue、DelayQueue、SynchronousQueue

    ConcurrentHashMap
    高效的线程安全哈希map。请对比hashTable , concurrentHashMap, HashMap

  • 管理类

           管理类的概念比较泛,用于管理线程,本身不是多线程的,但提供了一些机制来利用上述的工具做一些封装。
       了解到的值得一提的管理类:ThreadPoolExecutor和 JMX框架下的系统级管理类 ThreadMXBean
       ThreadPoolExecutor的一些参数解释:

     corePoolSize:池内线程初始值与最小值,就算是空闲状态,也会保持该数量线程。
     maximumPoolSize:线程最大值,线程的增长始终不会超过该值。
     keepAliveTime:当池内线程数高于corePoolSize时,经过多少时间多余的空闲线程才会被回收。回收前处于wait状态
     unit:时间单位,可以使用TimeUnit的实例,如TimeUnit.MILLISECONDS 
     workQueue:待入任务(Runnable)的等待场所,该参数主要影响调度策略,如公平与否,是否产生饿死(starving)
     threadFactory:线程工厂类,有默认实现,如果有自定义的需要则需要自己实现ThreadFactory接口并作为参数传入。

 

多线程

标签:实例   block   second   同步阻塞   执行   机器   请求   队列   自己的   

原文地址:http://www.cnblogs.com/hapiness/p/6475700.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!