美文网首页
java 并发 (concurrency)

java 并发 (concurrency)

作者: 巷及清晨 | 来源:发表于2020-03-15 23:46 被阅读0次

    一、进程和线程

    1、进程

    a、拥有自包含的执行环境

    b、拥有完整的、私有的运行时资源的集合

    c、拥有自己的内存空间

     进程的同义词有“程序”、“应用”,pipe、socket能够为一个系统中的不同进程,或者不同系统中的多个进程。

    2、线程

    a、轻量级的进程,存在于进程之中

    b、线程与进程共享内存、打开的文件

    对于开发者而言,启动的线程只有一个,那就是main()。

    Thread.slepp方法保证休眠的时间,因为时间会受到底层操作系统的影响。同时,休眠期间有可能会被Interrupt。

    即使代码中没有使用可能抛出异常的方法,也可以显式的判断有没有异常(比如用if),有的话进行处理。

    isInterrupt方法在alive的线程未被Interrupt时,返回false;不是alive的线程被Interrupt时也返回false。

    join()方法允许一个线程等待另一个线程执行结束再继续执行。

    3、线程冲突

    多个线程同时引用同一个对象,并且操作不是原子操作的时候,有可能会出现线程冲突。

    比如;i++操作,在jvm层面,该操作分为三步,多个线程同时执行i++,会出现interleave的情况,不能够保证每次执行(对应的jvm层面分解之后的操作)的顺序都是一样的。

    4、内存不一致错误

    对于多个线程共享的对象,一个线程对该对象写内存之后,对其他线程是可见的。

    例如:Thread A的修改对Thread B 不可见(A、B访问同一个对象)

    原始counter = 0;

    A线程先执行了counter++ ;但是B线程却打印counter=0(正确情况应该是1),那可能是因为A对counter的修改于B时不可见的,A、B之间并没有建立起happens-before的关系。

    解决方法:线程之间建立happens-before关系(比如使用join())。

    5、同步方法

    a、需要有一个共同的对象

    b、不能用在构造方法上,因为线程需要先创建对象然后再使用它。即便如此,也需要避免对象过早泄露。例如在构造函数中使用instances.add(this),在构造对象完成之前,其他的线程已经能够通过instances访问该对象。

    final类型的变量,对非同步方法而言是读安全的,但是有可能会引起liveness的问题。

    c、实现机制是使用了内部锁(监视锁),来达到以下目的

    1、强制对引用对象的独占访问

    2、建立起happens-before关系

    d、如果同步方法是static的,锁为Class对象

    6、同步方法块

    a、需要指定一个对象充当内部锁

    b、支持重入同步(同步方法块中的代码又调用了其他同步代码块中的代码,而且都使用相同的锁,循允许线程多次获得同一把锁来避免自身将自身阻塞)。

    7、原子操作

    1、操作要么完整执行,要么根本不执行,不存在中途停止执行的情况。

    2、c++不是原子操作

    3、原子操作不存在线程干扰问题,但是有可能出现内存不一致问题。

    4、所有的引用变量以及基本数据类型变量(除了long、double)的读写操作都是原子操作。

    5、所有被volatile修饰的变量(包括long、double)的读写操作都是原子操作。

    相关文章

      网友评论

          本文标题:java 并发 (concurrency)

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