java多线程并发编程与CPU时钟分配小议

我们先来研究下JAVA的多线程的并发编程和CPU时钟振荡的关系吧

老规矩,先科普

我们的操作系统在DOS以前都是单任务的

什么是单任务呢?就是一次只能做一件事

你复制文件的时候,就不能重命名了

那么现在的操作系统,我一边在这边写BLOG,一边听歌,一边开着QQ,一边……………………

显然,现在的操作系统都是多任务的操作系统

操作系统对多任务的支持是怎么样的呢?

每打开一个程序,就启动一个进程,为其分配相应空间(主要是运行程序的内存空间)

这其实就支持并发运行了

CPU有个时钟频率,表示每秒能执行CPU指令的次数,

在每个时钟周期内,CPU实际上只能执行一条(或者多条指令)。

操作系统对进程线程进行管理,

轮流(不是按顺序)为每个进程分配很短的一段时间(不一定均分),

然后在每个进程的内部,程序代码自己处理该进程内部线程的时间分配,

多个线程之间相互切换着去执行,

因为切换的时间非常非常短

因此,给人的感觉就是这多个任务、多个线程是在并发运行的

其实,从微观角度来看,

程序的运行还是异步的。

既然都是异步运行的

那么

我们的多线程运行

其实也只是CPU也只是一直在串行的运行着

根本就没有同时运行啊?

既然这样

那么我们多线程又有什么意义呢?

我们又知道

Cpu的运算速度实在是太快了

但是我们I/O的读取速度

网络的传输熟读

数据库的连接--读取速度

我们操作的速度

这些和CPU运算速度比起来

实在是太慢太慢了

因此

在我们进行这些操作的时候

其实CPU在多数情况下还是空闲着的

在这种情况下

我们运行多个任务多个线程

那么在进程A需要进行IO等操作时

CPU空闲就可以进行进程B的相关操作

而不是像串行的那样一定要线程A运行完了才能运行线程B

这也就提高了CPU的利用率

可能有些童鞋会在某些论坛或者什么地方看到

有关java多线程降低CPU运算速度的讨论和说法

这又是怎么回事呢?

其实,这个问题的关键是:

你到底要让CPU干嘛?

如果你让CPU进行的全是内部运算

(没有任何I/O    网络   数据库访问  等等…… )

那么,人为地硬折开CPU内部运算

用来给多个线程"分时"运算

那么CPU运算速度只能更慢

但是

如果你的业务不全是CPU内部运算

还有网络\数据库访问\I/O(如GUImouse操作)等等

则使用多线程有明显的好处

说了这么多

还没最重要的问题呢------多线程的目的

多线程的目的是为了最大限度的利用CPU资源

好了

那么我们继续讨论CPU的问题

CPU中

主频=外频×倍频

主频越高

一个时钟周期里面完成的指令数也越多

当然cpu的速度也就越快了

以前提高CPU运算速度的方法

就是提高CPU主频

但是随着时间的发展

cpu主频在一定程度上

已经达到了物理极限,很难再提高了

那么我们想再继续提高CPU性能应该怎么办呢?

我们知道

传统的CPU

只有一个内核

这个内核也只用同时运行一个线程

现在要提高CPU性能

我们可以在CPU的一个内核上

允许运行多个操作

从硬件级上实现多线程并发运行

为了提高CPU的运算性能

只有使用具有超线程技术的多核CPU

-------------我想这才是JAVA支持多线程并发运行的长久意义所在

说了这么多

再来回到我们的主题吧

java中多线程

1.  关于内存

前面已经说过

在操作系统下

每打开一个程序

系统就会为启动一个进程

为进程分配系统资源(运行程序所需的内存等)

在JAVA中

所有线程都归JVM调度

那么

在JAVA中的线程和系统下的进程在内存使用方面又会有哪些异同呢?

而在Java中所有变量都储存在主存中

对于所有线程都是共享的(在同一进程中)

每条线程都有自己的工作内存(Working Memory)

工作内存中保存的是主存中某些变量的拷贝

线程对所有变量的操作都是在工作内存中进行

线程之间无法相互直接访问

变量传递均需要通过主存完成

但是在程序内部可以互相调用(通过对象方法)

所有线程间的通信相对简单,速度也很快

进程间的内部数据和状态都是相互完全独立的

而进程间通信大多数情况是必须通过网络实现

线程本身的数据通常只有寄存器数据

以及一个程序执行时使用的堆栈

所以线程的切换比进程切换的负担要小

关于线程调度

前面说了

CPU对于各个线程的调度是随机的(分时调度)

在Java程序中,JVM负责线程的调度

线程调度是指------按照特定的机制为多个线程分配CPU的使用权

调度的模式有两种:

分时调度和抢占式调度。

分时调度是所有线程轮流获得CPU使用权,并平均分配每个线程占用CPU的时间;

抢占式调度是根据线程的优先级别来获取CPU的使用权。

JVM的线程调度模式采用了抢占式模式。

既然是抢占调度

那么我们就能通过设置优先级来“有限”的控制线程的运行顺序

注意“有限”一次

时间: 2024-10-10 10:55:11

java多线程并发编程与CPU时钟分配小议的相关文章

对JAVA多线程 并发编程的理解

对JAVA多线程并发编程的理解 Java多线程编程关注的焦点主要是对单一资源的并发访问,本文从Java如何实现支持并发访问的角度,浅析对并发编程的理解,也算是对前段时间所学的一个总结. 线程状态转换 Java语言定义了5中线程状态,在任何一个时间点,一个线程只能有且只有其中一种状态,这5中状态分别是: ?  新建(New):创建后尚未启动的线程处于这种状态 ?  运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程可能正在执行,也有可

Java 多线程并发编程面试笔录一览

知识体系图: 1.线程是什么? 线程是进程中独立运行的子任务. 2.创建线程的方式 方式一:将类声明为 Thread 的子类.该子类应重写 Thread 类的 run 方法 方式二:声明实现 Runnable 接口的类.该类然后实现 run 方法 推荐方式二,因为接口方式比继承方式更灵活,也减少程序间的耦合. 3.获取当前线程信息? Thread.currentThread() 4.线程的分类 线程分为守护线程.用户线程.线程初始化默认为用户线程. setDaemon(true) 将该线程标记为

Java多线程并发编程

Thread和Runnable Runnable接口可以避免继承自Thread类的单继承的局限性. Runnable的代码可以被多个线程(Thread的实例)所共享,适合于多个线程共享资源(其实就是持有同一个runnable实例)的情况. 以火车站买票为例,分别以继承Thread类和实现Runnable接口这两种方式来模拟3个线程卖5张票: 使用Thread类模拟卖票 1 class MyThread extends Thread{ 2 3 private int ticketCount = 5

Java多线程-并发编程模型

以下内容转自http://ifeve.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E6%A8%A1%E5%9E%8B/: 并发系统可以采用多种并发编程模型来实现.并发模型指定了系统中的线程如何通过协作来完成分配给它们的作业.不同的并发模型采用不同的方式拆分作业,同时线程间的协作和交互方式也不相同.这篇并发模型教程将会较深入地介绍目前(2015年,本文撰写时间)比较流行的几种并发模型. 并发模型与分布式系统之间的相似性 本文所描述的并发模型类似于分布式系统中使

java多线程 并发 编程

转自:http://www.cnblogs.com/luxiaoxun/p/3870265.html 一.多线程的优缺点 多线程的优点: 1)资源利用率更好 2)程序设计在某些情况下更简单 3)程序响应更快 多线程的代价: 1)设计更复杂 虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复杂.在多线程访问共享数据的时候,这部分代码需要特别的注意.线程之间的交互往往非常复杂.不正确的线程同步产生的错误非常难以被发现,并且重现以修复. 2)上下文切换的开销 当CPU从执行一个线程切

Java多线程并发编程/锁的理解

一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等方案后,问题得到解决. 限流方案见本人另一篇博客:Guava-RateLimiter实现令牌桶限流 二.乐观锁 & 悲观锁 1.乐观锁   顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号(versio

Java 多线程 并发编程 (转)

一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线程:表示程序的执行流程,是CPU调度执行的基本单位:线程有自己的程序计数器.寄存器.堆栈和帧.同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源. 2.Java标准库提供了进程和线程相关的API,进程主要包括表示进程的jav

Java 多线程 并发编程

转自: http://blog.csdn.net/escaflone/article/details/10418651 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线程:表示程序的执行流程,是CPU调度执行的基本单位:线程有自己的程序计数器.寄存器.堆栈和帧.同一进程中的线程共用相同的地址空

java多线程 并发编程

一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线程:表示程序的执行流程,是CPU调度执行的基本单位:线程有自己的程序计数器.寄存器.堆栈和帧.同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源. 2.Java标准库提供了进程和线程相关的API,进程主要包括表示进程的jav