一、线程的调度方式

  线程调度分为两种方式: 协同式调度和抢占式调度。
协同式调度:线程的执行时间由线程本身控制,线程将工作执行完之后,通知操作系统切换到其他线程上。缺点:时间不可控,就算出问题,也不会通知操作系统切换,容易阻塞。
抢占式调度:每个线程由操作系统来分配执行时间,调度。java的线程就是基于抢占式实现的。
通过线程优先级来控制执行时间。

二、线程的状态

(1)新建:创建后,未启动的线程。
(2)运行:此状态的线程,可能在执行,也有可能是在等待操作系统分配资源。
(3)无限期等待:不分配cpu时间,等待被唤醒。
(4)限期等待:不会分配cpu时间,不过无需等待其他线程唤醒,会自动唤醒。
(5)阻塞:等待资源。
(6)等待:等待唤醒。
(7)结束:已终止的线程。

三、线程安全

  当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行其他任何协调操作,调用这个对象的行为都可以获取正确的结果,则这个对象是线程安全的。

java各种操作共享的数据分为以下5类:
(1)不可变
在java中,不可变的对象都是线程安全的。final修饰的对象,都是线程安全的。
(2)绝对线程安全
java中,标榜自己是线程安全的,往往都不是绝对线程安全的。
如Vector ,虽然add、get等方法都是用synchronized修饰,但并不是绝对线程安全带 。
(3)相对线程安全
保证对对象单独操作,是线程安全的。如Vector。
(4)线程兼容
线程兼容是指对象本身不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全的使用。
(5)线程对立
线程对立是指无论调用端采取了何种措施,都无法在多线程环境中并发使用的代码。

3.1 synchronized

synchronized经过编译之后,是在同步块前后分别加上monitorenter和monitorexit这两个字节码指令。

(1)修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。相当于synchronized(A.class)
(2)修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
(3)修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。锁的是this。也就是当前的对象。
(4)修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象。锁的是Class对象,也就是A.class.相当于全局锁,线程在该类中所有操作不能进行。

3.2 ReentrantLock

(1)等待可中断:
  指拥有锁的线程长期不释放锁,正在等待的线程可以放弃等待。
(2)公平锁:
  公平锁是指多个线程在等待同一个锁时,需要按照申请锁的时间顺序来获取到锁。
  非公平锁是指多个线程在等待同一个锁时,获取到锁的概率是相同的。
  ReentrantLock默认是非公平锁,但是可以构造出公平锁。

3.3 可重入代码

  可以在代码执行的任意时刻中断它,转而去执行其他代码,在得到控制权之后,原来的程序不会出现任何错误,这个代码就为可重入代码。
可重入代码是线程安全的。

3.4 ThreadLocal

  如果一段代码中所需要的数据必须与其他代码共享,那么最好将这些代码放在同一个线程中执行。这样,我们可以用ThreadLocal来实现数据在同一个线程中共享,而不会出现数据争用。
  每个线程对象中,都有一个ThreadLocalMap对象,用来存放线程本地变量,变量只线程中的代码可见。其中最经典的一个应用就是,一个web端请求,对应一个服务器端线程,用以做上下文。spring 的数据库连接管理,hibernate的session管理。ThreadLocal模式解决的是同一线程中隶属于不同开发层次的数据共享问题,而不是在不同的开发层次中进行数据传递。

3.5 数据共享 OR 数据传递

  ThreadLocal模式与synchronized关键字都是用于处理多线程并发访问变量的问题。只是两者处理问题的角度和思路不同。
(1)ThreadLocal是一个Java类,通过对当前线程(Thread)中的局部变量的操作来解决不同线程的变量访问的冲突问题。所以,ThreadLocal提供了线程安全的共享对象机制,每个线程(Thread)都拥有其副本。
(2)Java中的synchronized是一个保留字,它依靠JVM的锁机制来实现临界区的函数或者变量在访问中的原子性。在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。此时,被用作“锁机制”的变量是多个线程共享的。
  同步机制采用了“以时间换空间”的方式,提供一份变量,让不同的线程排队访问。而ThreadLocal采用了“以空间换时间”的方式,为每一个线程都提供了一份变量的副本,从而实现同时访问而互不影响。

JVM线程安全的更多相关文章

  1. 【操作系统】二、JVM线程与Linux内核线程的映射

    Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...

  2. JVM线程状态,park, wait, sleep, interrupt, yeild 对比

    ---恢复内容开始--- JVM线程状态 NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED BLOCKED是等待获得对象锁 WAIT ...

  3. JVM线程与Linux内核线程的映射[转]

    Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...

  4. JVM线程状态Running、Sleeping、Wait、Park、Monitor

    1,使用JVisualVM时,打开Threads监控,我们可以发现Java的线程状态有以下几种: 2,JVM线程状态: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_W ...

  5. 深入理解JVM线程模型

    1. jvm内存模型在描述jvm线程模型之前,我们先深入的理解下,jvm内存模型.在jvm1.8之前,jvm的逻辑结构和物理结构是对应的.即Jvm在初始化的时候,会为堆(heap),栈(stack), ...

  6. 任务队列方案详解(一)JVM线程池

    前言 我们都知道 web 服务的工作大多是接受 http 请求,并返回处理后的结果.服务器接受的每一个请求又可以看是一个任务.一般而言这些请求任务会根据请求的先后有序处理,如果请求任务的处理比较耗时, ...

  7. jvm 线程实现机制

    简单记一下 实际上jvm 规范中并无做限制. 不同的jvm实现上存在一定差异.技术上的选择主要在 jvm的线程是如何和操作系统的线程对应的.有1:1 的线程实现模式,也有N:1的线程实现模式,更有M: ...

  8. 【转】java jvm 线程 与操作系统线程

    原文链接:http://segmentfault.com/q/1010000000370403 Java的目标是要跨平台,而不同的操作系统(如类Unix和Windows)其任务调度机制有很大的不同,故 ...

  9. [Java Performance] JVM 线程调优

    调整线程栈空间 当很缺少内存时,能够调整线程使用的内存. 每一个线程都有一个栈,用来记录该线程的调用栈信息.线程中的栈的默认空间是有OS和JVM的版本号决定的: OS 32-bit 64-bit Li ...

随机推荐

  1. How to Iterate Over a Map in Java?(如何遍历Map)

    1.Iterate through the "entrySet" like so: public static void printMap(Map mp) { Iterator i ...

  2. C语言中static作用

    在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条. (1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有 ...

  3. POJ3321/Apple tree/(DFS序+线段树)

    题目链接 Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9692 Accepted: 3217 Descr ...

  4. Android中获取网络数据时的分页加载

    //此实在Fragment中实现的,黄色部分为自动加载,红色部分是需要注意的和手动加载,    蓝色部分是睡眠时间,自我感觉不用写  ,还有就是手动加载时,不知道为什么进去后显示的就是最后一行,求大神 ...

  5. CSS的命名

    使用约定俗称的命名规范有助于我们的代码阅读和维护. 常用命名: wrap  外套       ———————— 用于最外层 container 容器  ————————  和外套相似,用于做容器 he ...

  6. POJ - 2336 Wireless Network

    Description An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have ...

  7. Java8学习笔记----Lambda表达式 (转)

    Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家       本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...

  8. 优化之zencart第一时间修改原始内容

    Zen Cart 基本修改指南 Zen Cart,全球顶级B2C商城网站!要想自行搭建一个基本的Zen Cart的网站,这篇文章是绝对不能错过的.目前我已经做了两个B2C网站,但是还是离不开这篇文章的 ...

  9. PAT1002

    This time, you are supposed to find A+B where A and B are two polynomials. 这一次,你被要求计算A+B当A和B是两个多项式的时 ...

  10. JS的数据类型转换

    JS 数据类型转换 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...