[关闭]
@frank-shaw 2015-10-29T10:57:15.000000Z 字数 2247 阅读 2915

Java线程与电脑CPU的关联

java.多线程


线程的实现

并发编程中,我们会讲到多线程(当然也有可能会有多进程,最近也有异步编程以及协程的概念,都不是特别了解),同时还会牵扯到多CPU。此时,我们想要知道的是:Java中的多线程与实际操作系统的CPU 之间的关系是怎样的呢?

我们都知道,线程是比进程更轻量级的调度执行单元,线程的引入,可以把一个进程的资源分配和调度分开,各个线程既可以共享进程资源,又可以独立调度(线程是CPU调度的基本单位)。

讲到线程与进程,可以发现,一个JVM就是一个进程啊。

主流的操作系统都提供了线程实现,Java语言则提供了在不同硬件和操作系统平台下线程操作的统一处理,每个已经执行start()方法且还未结束的java.lang.Thread类的实例就代表了一个线程。值得注意的是,在Java API中的Thread类显得很特别,因为它的所有关键方法都是声明为native的(查看了下,并没有发现啊。。)。这样做的原因是为了使用平台相关的手段可以提高执行效率。

线程实现的方式

线程实现的方式是很多的,如内核线程的实现方式、使用用户线程实现、使用用户线程加轻量级进程混合实现。而,Java线程在Windows及Linux平台上的实现方式,现在看来,是内核线程的实现方式。下面主要讲解的就是内核线程实现。

1.使用内核线程实现

内核线程(KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操纵调度器(scheduler)对线程进行调度,并负责将线程的任务映射到各个处理器上。每个内核线程可以视为内核的一部分。支持多线程的内核就叫做多线程内核。

当然,程序一般都不会去直接使用内核线程,而是去使用内核线程的一个高级接口--轻量级进程(LWP),轻量级继承就是我们通常意义上所讲的线程,由于每个轻量级进程都由一个内核线程支持,因此只有先支持内核进程,才能有轻量级进程。这种轻量级进程与内核线程之间1:1的关系称为1对1的线程模型。

java中的线程调度方式
线程调度是指系统为线程分配处理器使用权的过程,主要调度方式有两种:协同式线程调度和抢占式线程调度。Java使用的线程调度方式就是抢占式调度。在JDK后续版本中有可能会提供协程方式来进行多任务处理。

由此想到的问题:
1.Java线程数量是由什么来决定的呢?
2.Java线程数量与CPU个数的关系是什么呢?
3.Java线程池相关的知识点?可以参考之前写过的:https://www.zybuluo.com/mdeditor#159439

为了回答前两个问题,我们可以尝试自己去编程实现

package 检测线程数量影响因素;

/*
 * 此程序的目的在于测试一个电脑最多允许执行的线程数
 * 
 * 在本电脑上,最终执行数量为29546,最终死机
 * 
 * 电脑参数:CPU:i5   RAM:4G
 * 
 * 设置JVM的内存参数以及查看JVM的可执行的内存多少
 * 可以查看http://www.iteye.com/problems/54114 
 * 里面有详细解释。
 * 
 * 可以给Java虚拟机设置使用的内存,但是如果你的选
 * 择不对的话,虚拟机不会补偿。可通过命令行的方式
 * 改变虚拟机使用内存的大小。如下表所示有两个参数
 * 用来设置虚拟机使用内存的大小。 
 * 参数描述 
 * -Xms JVM初始化堆的大小 
 * -Xmx JVM堆的最大值
 * 
 * 更多可以参考这篇文章:
 * http://blog.csdn.net/fenglibing/article/details/5488494
 * 
 * 通过编程检测,发现分配给JVM的内存大小是892M。
 *  
 * 回到我们的问题:一共可以得到多少个线程。基本上可以得到:
 * (JVM能够被分配到的内存总数-已经使用的内存数)/线程栈大小吧
 * 
 * 
 * 那么,另一个问题来了,Java线程数量与CPU个数的关系是什么?
 * 答案是无法确定。不同情况下的多线程与CPU的关系不同,比如IO密集型
 * 与计算密集型的线程之间都有不同的关系。我感觉这个已经涉及到了
 * 分布式方面的知识了。可以终止了。
 */

public class ThreadMax {
    static int i =0;
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        /*
         * 检测可以运行的线程最大数量
         */
        /*for(; ; i++){
            new Thread(new Runnable(){

                @Override
                public void run() {
                    while(true){
                        try{
                            Thread.sleep(20);
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                        System.out.println("线程数:"+i);
                    }

                }

            }).start();
        }*/

        /*
         * 检测JVM被分配内存的大小
         */
//      System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);
//      System.out.println(Runtime.getRuntime().totalMemory()/1024/1024);
//      System.out.println(Runtime.getRuntime().freeMemory()/1024/1024);

        /*
         * 检测每一个线程的线程栈的大小,竟然不成功。。。只能通过指令来查找
         */
        System.out.println(Thread.currentThread());

    }

}
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注