多线程和并发。

  • 不推荐覆写start方法
  • 启动线程前stop方法是不可靠的
  • 不使用stop方法停止线程

        有以下三个问题:

        1、stop方法是过时的

        2、stop方法会导致代码逻辑不完整

        3、stop方法会破坏原子逻辑

        如果期望终止一个正在运行的线程,则不能使用已经过时的stop方法,需要自行编码实现,如此即可保证原子逻辑不被破坏,代码逻辑不会出现异常。当然,如果我们使用的是线程池(比如ThreadPoolExecutor类),那么可以通过shutdown方法逐步关闭池中的线程,他采用的是比较温和、安全的关闭线程方法,完全不会产生类似stop方法的弊端。

  • 线程优先级只使用三个等级
        线程优先级推荐使用MIN_PRIORITY、NORM_PRIORITY、MAX_PRIORITY三个级别,不建议使用其他7个数字。
  • 使用线程异常处理器提升系统可靠性

        Java 1.5版本以后在Thread类中增加了setUncaughtExceptionHandler方法,实现了线程异常的捕捉和处理。

        实际环境中应用,需要注意以下三个方面:

        1、共享资源锁定

        2、脏数据引起系统逻辑混乱

        3、内存溢出

  • volatile不能保证数据同步
        注意:volatile不能宝恒数据是同步的,只能保证线程能够获得最新值。
  • 异步运算考虑使用Callable接口

        从Java 1.5开始引入了一个新的接口Callable,他类似于Runable接口,实现他就可以实现多线程任务。

        此类异步计算的好处是:

        1、尽可能多地占用系统资源,提供快速运算。

        2、可以监控线程执行的情况,比如是否执行完毕、是否有返回值、是否有异常等。

        3、可以为用户提供更好的支持,比如例子中的运算进度等。

  • 优先选择线程池

        一个线程的运行时间分为三部分:T1为线程启动时间,T2为线程体的运行时间,T3为线程销毁时间,如果一个线程不能被重复使用,每次创建一个线程都需要经过启动、运行、销毁这三个过程,那么这势必会增大系统的响应时间,有没有更好的办法降低线程的运行时间呢?

        T2是无法避免的,只有通过优化代码来实现降低运行时间。T1和T2都可以通过线程池(Thread Pool)来缩减时间,比如在容器(或系统)启动时,创建足够多的线程,当容器(或系统)需要时直接从线程池中获得线程,运算出结果,再把线程返回到线程池中。

        线程池的创建过程:创建一个阻塞队列以容纳任务,在第一次执行任务时创建足够多的线程(不超过许可线程数),并处理任务,之后每个工作线程自行从任务队列中获得任务,直到任务队列中的任务数量为0为止,此时线程将处于等待状态,一旦有任务再加入到队列中,即唤醒工作线程进行处理,实现线程的可复用性。

        使用线程减少的是线程的创建和销毁时间。

  • 适时选择不同的线程池来实现、

        Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供了一个Executors的静态类,他可以直接生成多种不同的线程池执行器,比如单线程执行器、带缓冲功能的执行器等,但归根结底还是使ThreadPoolExecutor类或ScheduledThreadPoolExecutor类的封装性。

        newSingleThreadExecutor、newCachedThreadPool、newFixedThreadPool是线程的简化版,而ThreadPoolExecutor则是旗舰版——简化版更容易操作,需要了解的知识相对少些,方便实用,而且旗舰版功能齐全,适用面广,但难于驾驭。

  • Lock与synchronized是不一样的

        显示锁和内部锁的不同之处:

        1、Lock支持更细粒度的锁控制

        2、Lock是无阻塞锁,synchronized是阻塞锁

        3、Lock可实现公平锁,synchronized只能是非公平锁

        4、Lock是代码级的,synchronized是JVM级的

        根据实际情况考虑:灵活、强大则选择Lock,快捷、安全则选择synchronized。

  • 预防线程死锁

        在我们Java多线程并发编程中,死锁很难避免,也不容易预防,对付他的最好办法是测试:提高测试覆盖率,建立有效地边界测试,加强资源监控,这些方法能使死锁无处遁形,即使发生了死锁现象也能迅速查找到原因,提高系统的可靠性。

  • 适当设置阻塞队列长度
  • 使用CountDownLatch协调子线程
  • CyclicBarrier让多线程齐步走
        在多线程编程中,两个线程独立运行,在没有线程间通信的情况下,如何解决两个线程汇集在同一远点的问题。Java提供了CyclicBarrier(关卡,也有翻译为栅栏)工具类来实现。

猜你喜欢

转载自blog.csdn.net/en_joker/article/details/80563358