原文链接:http://segmentfault.com/q/1010000000370403

Java的目标是要跨平台,而不同的操作系统(如类Unix和Windows)其任务调度机制有很大的不同,故Java在JVM层面抽象了一套自己的线程机制,用以映射不同的操作系统的任务调度。如你所述的一些缺点,Java在1.1版本之后,这个线程模块就是基于内核级别线程[1]

首先,如果一个机器上只有一个逻辑CPU,此时系统调度器通过轮换时间片的方式来调度任务,所以不存在真正的并行,只是并发;只有多个逻辑CPU的情形下,才会出现并行;

其次,对于不同的操作系统,其任务调度机制不同:

  1. 对于类Unix系统而言,一般都是进程作为任务的调度单位,也即是操作系统调度器,只会针对进程来分配CPU等资源。由于进程彼此独立,相互不可进行直接访问,这增加了应用的通信成本。所以后面有了微进程,微进程与进程不同的是,允许一定程度上,彼此可以直接进行访问,详细可参考LinuxThreads。JVM在一些类Unix平台下,就是将线程映射到操作系统的微进程,来实现线程调度。这样多线程能够直接被系统调度器进行调度,与此对应的就是其线程的创建和销毁的成本就比较高,而且JVM的线程优先级很难进行匹配,无法提供确切的保证,仅仅是个hint。需要说明的是在linux2.6之后,LinuxThreadsNPTL所取代,NPTL提供了1:1形式的线程模型,即每个线程一一对应一个内核调度实体,这样即是内核级别的线程。同样NPTL额外提供可替换的M:N模型Thread
    linux下jvm创建Thread的调用(openJDK-6-src-b27中的os_linux.cpp中的bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size)中调用以下API):
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
    具体的后续调用跟踪,请参考pthread的实现;
  2. 对于Windows系统而言,从其一开始线程就是系统进行调度的最小单位,即Wiki[Thread]中所述的1:1模型。而对于用户态线程和内核态线程,一般是针对N:1模型和M:N模型,即多个用户态线程映射到一个内核线程,系统调度器的调度单位是内核态线程,对用户态线程一无所知。个人对windows的线程模型不是十分了解,按照NPTL和Wiki[Thread]和中的描述,觉得windows直接将线程作为调度单位,不存在用户态线程和内核态线程的区别。需要说明的是,JVM定义的线程优先级和Windows的线程优先级能够很好地匹配。
    windows下jvm创建Thread的调用-(openJDK-6-src-b27中的os_windows.cpp中的bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size)中调用以下API):
    HANDLE thread_handle = (HANDLE)_beginthreadex(NULL, (unsigned)stack_size, (unsigned (__stdcall *)(void*)) java_start, thread, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id);
    具体后续调用请参考windows的API;

最后,回答你的问题:

    1. Java的多线程不是骗人,针对不同的操作系统进行适配,确实实现了并发和并行;
    2. 用户级别线程通常发生在进程级别,一般通过系统调用等不同的实现方式来模拟实现并发,而内核级别线程则一般由系统的调度器来调度,是原生级别的并发;
    3. 内核级别线程有系统调度器调度,肯定可以享受多核的好处,而用户级别线程是通过模拟实现调度,由于其映射的调度实体(进程或者映射的内核级线程)才是系统调度器的调度单位,所以与内核级线程相比,其对资源的访问确实存在一定的限制。详细的内容或者想继续深入了解,请再多参考参考wiki等文献

【转】java jvm 线程 与操作系统线程的更多相关文章

  1. 浅谈java中线程和操作系统线程

    在聊线程之前,我们先了解一下操作系统线程的发展历程,在最初的时候,操作系统没有进程线程一说,执行程序都是串行方式执行,就像一个队列一样,先执行完排在前面的,再去执行后面的程序,这样的话很多程序的响应就 ...

  2. java线程和操作系统线程的异同(大图对比)

    先看看两者的对比: 可以发现: 1.java中细分了阻塞,将阻塞给分成了三个不同类型的阻塞. 2.java没有区分就绪状态和运行状态.java将这两种状态合并成runnable状态. 3.还有一个容易 ...

  3. (转)java中的进程与线程

    (转自地址http://www.ibm.com/developerworks/cn/java/j-lo-processthread/) Java 进程的建立方法 在 JDK 中,与进程有直接关系的类为 ...

  4. Java 线程和操作系统的线程有啥区别?

    尽人事,听天命.博主东南大学硕士在读,携程 Java 后台开发暑期实习生,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收 ...

  5. Java学习之二(线程(了解) JVM GC 垃圾回收)

    线程与进程(了解)→JVM→字节码→GC 一.程序 = 算法 + 数据结构(大佬) 二.程序 = 框架 + 业务逻辑(现实) 1.线程与进程.同步与异步 1.1进程是什么? 进程就是操作系统控制的基本 ...

  6. java笔记--关于多线程如何查看JVM中运行的线程

    查看JVM中的线程 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3890280.html "谢谢-- ThreadGrou ...

  7. Java中的进程和线程

     Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...

  8. Java中的进程与线程(总结篇)

    详细文档: Java中的进程与线程.rar 474KB 1/7/2017 6:21:15 PM 概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进 ...

  9. 转:Java Web应用中调优线程池的重要性

    不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文主要介绍Java线程池的使用和如何正确的配置线程 ...

随机推荐

  1. linux运维、架构之路-Zabbix监控应用及分布式

    一.Zabbix监控集群应用 1.监控端口 net.tcp.listen[port] 检查 TCP 端口 是否处于侦听状态.返回 0 - 未侦听:1 - 正在侦听 net.tcp.port[<i ...

  2. docker、oci、runc以及kubernetes梳理

    容器无疑是近年来云计算中最火热的关键词.随着docker的大热,docker.oci.runc.containerd等等名词也逐渐传播开来.这么多的名词,也容易让人混淆.本文对相关名词和其之间的联系进 ...

  3. 安卓图片加载框架之Glide框架

    Glide框架加载有两种,第一,是加载图片,第二是加载布局背景.首先我来说说第一种情况加载图片. Glide.with(getActivity()).load(lists.get(position). ...

  4. 05.haproxy+mysql负载均衡 整合 redis集群+ssm

    本篇重点讲解haproxy+mysql负载均衡,搭建完成后与之前搭建的redis+ssm进行整合 (注:这里用到了两台mysql数据库,分别安装两台虚拟机上,已经成功实现主主复制,如果有需要,请查看我 ...

  5. java-8u151-64安装与配置环境变量

    去oracle官网下载 java jdk for developments(最新发布的java9与java8有很大差别,选择8就够用了) 我是装在默认的C盘里的,直接配置环境变量了 新建JAVA_HO ...

  6. 用shell制作IP脚本

    vim  ip.sh #!/bin/bashread -p "eth:" eread -p "ip:" ip1read -p "netmask:&qu ...

  7. Android中相机和相冊使用分析

    Android中相机和相冊使用分析 欢迎转载,但请尊重原创(文章来自不易,转载请标明转载出处,谢谢) 在手机应用程序中,使用自带的相机拍照以及相冊选择喜欢的图片是最常见只是的用户需求,那么怎么合理使用 ...

  8. C#基础知识 简单说明泛型的优点

    有关泛型的优缺点在网上有很多篇文章,也足以说明问题,我就不去复制粘贴了(而且内容有些多),由于记性不太好,所以自己做个简单明了的总结. 泛型的优点主要有两个: "性能" " ...

  9. 一个简单的双向链表(C++实现)

    直接上代码,亲测有用. #ifndef __DLINK_H__ #define __DLINK_H__ /* [phead] -> [index0] -> [index1] -> [ ...

  10. 【转载】Java系列笔记(1) - Java 类加载与初始化

    Java系列笔记(1) - Java 类加载与初始化 原文地址:http://www.cnblogs.com/zhguang/p/3154584.html 目录 类加载器 动态加载 链接 初始化 示例 ...