美文网首页
java 多线程

java 多线程

作者: bradyjoestar | 来源:发表于2017-08-20 21:04 被阅读0次

    java 多线程

    原文链接

    前言

    线程安全出现的问题例子:

    比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。

    在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;

    而如果是在多线程情况下,比如有两个线程,线程 A 先将元素1存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B向此 ArrayList 添加元素2,因为此时 Size 仍然等于 0 (注意,我们假设的是添加一个元素是要两个步骤,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值,结果Size等于2。

    那好,我们来看看 ArrayList 的情况,期望的元素应该有2个,而实际只有一个元素,造成丢失元素,而且Size 等于 2。这就是“线程不安全”了。

    线程安全主要是由于:共享变量及共享变量的修改引起的问题。

    相应的解决方法是:

    线程中的局部变量不需要同步;线程内操作的,同时线程外需要用到的,需要同步!

    讲解

    如果对什么是线程、什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内。

    用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的“生产者,消费者模型”。

    很多人都对其中的一些概念不够明确,如同步、并发等等,让我们先建立一个数据字典,以免产生误会。

    • 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
    • 并行与并发
      • 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
      • 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。

    好了,让我们开始吧。我准备分成几部分来总结涉及到多线程的内容:

    • 扎好马步:线程的状态
    • 内功心法:每个对象都有的方法(机制)
    • 太祖长拳:基本线程类
    • 九阴真经:高级多线程控制类

    找好马步:线程的状态

    如下图所示:

    线程状态

    内功心法:每个对象都有的方法(机制)

    synchronized, wait, notify 是任何对象都具有的同步工具。

    太祖长拳:基本线程类

    基本线程类指的是Thread类,Runnable接口,Callable接口,Thread 类实现了Runnable接口.

    九阴真经:高级多线程控制类

    以上都属于内功心法,接下来是实际项目中常用到的工具了,Java1.5提供了一个非常高效实用的多线程包:java.util.concurrent, 提供了大量高级工具,可以帮助开发者编写高效、易维护、结构清晰的Java多线程程序。

    1.ThreadLocal类

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

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

    原子类(AtomicInteger、AtomicBoolean……)

    5.管理类(最常用)

    管理类的概念比较泛,用于管理线程,本身不是多线程的,但提供了一些机制来利用上述的工具做一些封装。

    了解到的值得一提的管理类:ThreadPoolExecutor和 JMX框架下的系统级管理类 ThreadMXBean

    ThreadPoolExecutor

    如果不了解这个类,应该了解前面提到的ExecutorService,开一个自己的线程池非常方便:

    相关文章

      网友评论

          本文标题:java 多线程

          本文链接:https://www.haomeiwen.com/subject/ndhqdxtx.html