java并发编程 (一) 《基本知识》

来源:互联网 发布:腾讯软件 编辑:程序博客网 时间:2024/06/07 14:45

    • 1线程知识
      • 11 进程线程和协程的关系
      • 12 多线程一定快么
      • 13 线程的上下文切换
      • 14 死锁
    • 2并发原子性
    • 3并发可见性

1.1线程知识

1.1.1 进程,线程和协程的关系

进程不共享堆,也不共享栈,由操作系统统一调度。
线程共享堆,但不共享栈,由操作系统统一调度。
协程共享推,但不共享栈,由开发自己负责任务的调度,没有了像线程上线问切换的开销.

1.1.2 多线程一定快么?

不一定,并发的情况下线程有创建和上下文切换的开销,执行数据量小的情况下,单线程更有优势.

1.1.3 线程的上下文切换

多线程竞争锁资源时,会产生上下文的切换。
解决方案 :

  • 无锁并发编程 :
    多线程处理数据的时候,避免使用锁,可以将(数据ID%线程数)取模分段,这样不同的线程处理不同的数据。
  • CAS算法:
    **通过自旋(不断循环)的方式,将预期的值(旧的值)和主存中的值对比看有没有变化,若变化则表示其他线程更改了共享值,要重新获取最新的值在进行操作;若没变化就将要更新的值刷入主存。**Java的Auomic包下类就使用的CAS算法,不需要加锁
  • 使用最少的线程:合理设置线程数。比如任务少,但是创建了很多线程在等待。线程WAIT状态的线程到RUNNABLE状态是需要上下文切换的开销的.
  • 协程: 在单线程里实现多任务的调度,并在单线程里维持多任务的切换。

1.1.4 死锁

通过jstack方式查找线程状态为BLOCK的线程

1.2并发原子性

原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。Java的concurrent包下提供了一些原子类,我们可以通过阅读API来了解这些原子类的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。

1.3.并发可见性

可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。比如 volatile int a = 0;之后有一个操作 a++;这个变量a具有可见性,但是a++ 依然是一个非原子操作,也就这这个操作同样存在线程安全问题。

0 0
原创粉丝点击