@frank-shaw
2015-10-29T10:57:15.000000Z
字数 2247
阅读 2942
java.多线程
并发编程中,我们会讲到多线程(当然也有可能会有多进程,最近也有异步编程以及协程的概念,都不是特别了解),同时还会牵扯到多CPU。此时,我们想要知道的是:Java中的多线程与实际操作系统的CPU 之间的关系是怎样的呢?
我们都知道,线程是比进程更轻量级的调度执行单元,线程的引入,可以把一个进程的资源分配和调度分开,各个线程既可以共享进程资源,又可以独立调度(线程是CPU调度的基本单位)。
讲到线程与进程,可以发现,一个JVM就是一个进程啊。
主流的操作系统都提供了线程实现,Java语言则提供了在不同硬件和操作系统平台下线程操作的统一处理,每个已经执行start()方法且还未结束的java.lang.Thread类的实例就代表了一个线程。值得注意的是,在Java API中的Thread类显得很特别,因为它的所有关键方法都是声明为native的(查看了下,并没有发现啊。。)。这样做的原因是为了使用平台相关的手段可以提高执行效率。
线程实现的方式是很多的,如内核线程的实现方式、使用用户线程实现、使用用户线程加轻量级进程混合实现。而,Java线程在Windows及Linux平台上的实现方式,现在看来,是内核线程的实现方式。下面主要讲解的就是内核线程实现。
内核线程(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());
}
}