请教多线程基础问题。

SilentHunter460 2020-09-06 02:52:06
多线程的是什么意思:
1)3个人同时搬3堆砖头。
2)1个人同时搬3堆砖头,这堆砖头还没搬完就去搬另一堆。如果是这种的话有什么意义?

从以下例子打印出来的效果看,似乎是第2种解释。
public class TaskThreadDemo {
public static void main(String[] args) {
//创建任务
Runnable printA = new PrintChar('a', 10000);
Runnable printB = new PrintChar('b', 100);
Runnable print100 = new PrintNum(100);
//创建线程
Thread thread1 = new Thread(printA);
Thread thread2 = new Thread(printB);
Thread thread3 = new Thread(print100);
//启动线程
thread1.start();
thread2.start();
thread3.start();
}
}

class PrintChar implements Runnable{
private char charToPrint;
private int times;
public PrintChar(char c, int t){
charToPrint = c;
times = t;
}
@Override
public void run() {
for (int i = 0; i < times; i++) {
System.out.print(charToPrint);
}
}
}

class PrintNum implements Runnable{
private int lastNum;
public PrintNum(int n){
lastNum = n;
}
@Override
public void run() {
for (int i = 0; i < lastNum; i++) {
System.out.print(" " + i);
}
}
}
...全文
3520 点赞 收藏 24
写回复
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
引用 22 楼 qq_16774199 的回复:
[quote=引用 21 楼 qq_33413127 的回复:] 一个售票员。1分钟卖一张票,10个售票员1分钟就能卖10张票,1000张票本来1000分钟才能做完的事,10个售票员100分钟就能卖完,本来要花16个小时,10个人一起卖票只需要花1.6个小时,这难道不是增加了效率吗
我想多线程本质应该是这样,不知道对不对: 如果是单核CPU,只能有1个售票员。1个人在10个窗口来回跑,但是跑得足够快,像光速那么快,于是你觉得每个窗口都有人售票。 如果是双核CPU,只能有2个售票员…… 如果是十核CPU,就不需要10个窗口来回跑了,但如果窗口增加到100个,就又要来回跑了。[/quote
引用 24 楼 qq_16774199 的回复:
[quote=引用 23 楼 qq_33413127 的回复:]天秀,经常看到几千个线程一起跑的,那人家的电脑都是一万核的CPU吗
我想应该是每个核负责跑几百个线程。然后切换足够快,于是你觉得所有线程在同时跑。 [/quote]你要不要先去了解一下线程和进程
回复
SilentHunter460 2020-09-11
引用 21 楼 qq_33413127 的回复:
一个售票员。1分钟卖一张票,10个售票员1分钟就能卖10张票,1000张票本来1000分钟才能做完的事,10个售票员100分钟就能卖完,本来要花16个小时,10个人一起卖票只需要花1.6个小时,这难道不是增加了效率吗
我想多线程本质应该是这样,不知道对不对: 如果是单核CPU,只能有1个售票员。1个人在10个窗口来回跑,但是跑得足够快,像光速那么快,于是你觉得每个窗口都有人售票。 如果是双核CPU,只能有2个售票员…… 如果是十核CPU,就不需要10个窗口来回跑了,但如果窗口增加到100个,就又要来回跑了。
回复
引用 20 楼 qq_16774199 的回复:
[quote=引用 18 楼 qq_33413127 的回复:]你举得例子不够生动形象,其实都是面向对象,例如火车站只有一个窗口再卖火车票,100个人买要排100个人的长队,这可以看做一个线程,火车站有10个窗口在卖火车票,100个人来买票,每个窗口排10个左右,这个卖票的时间是不是就大大的减少了呢,但是也并不是线程越多就越好,假如来了1000个人买票,你觉得火车站会给你开1000个窗口吗
买票的时间长短和窗口有关,但还有售票员人数这个重要因素,所以我才感觉线程并不一定能增加多少效率。[/quote] 一个售票员。1分钟卖一张票,10个售票员1分钟就能卖10张票,1000张票本来1000分钟才能做完的事,10个售票员100分钟就能卖完,本来要花16个小时,10个人一起卖票只需要花1.6个小时,这难道不是增加了效率吗
回复
SilentHunter460 2020-09-11
引用 23 楼 qq_33413127 的回复:
天秀,经常看到几千个线程一起跑的,那人家的电脑都是一万核的CPU吗
我想应该是每个核负责跑几百个线程。然后切换足够快,于是你觉得所有线程在同时跑。
回复
引用 22 楼 qq_16774199 的回复:
[quote=引用 21 楼 qq_33413127 的回复:] 一个售票员。1分钟卖一张票,10个售票员1分钟就能卖10张票,1000张票本来1000分钟才能做完的事,10个售票员100分钟就能卖完,本来要花16个小时,10个人一起卖票只需要花1.6个小时,这难道不是增加了效率吗
我想多线程本质应该是这样,不知道对不对: 如果是单核CPU,只能有1个售票员。1个人在10个窗口来回跑,但是跑得足够快,像光速那么快,于是你觉得每个窗口都有人售票。 如果是双核CPU,只能有2个售票员…… 如果是十核CPU,就不需要10个窗口来回跑了,但如果窗口增加到100个,就又要来回跑了。[/quote]天秀,经常看到几千个线程一起跑的,那人家的电脑都是一万核的CPU吗
回复
SilentHunter460 2020-09-10
引用 18 楼 qq_33413127 的回复:
你举得例子不够生动形象,其实都是面向对象,例如火车站只有一个窗口再卖火车票,100个人买要排100个人的长队,这可以看做一个线程,火车站有10个窗口在卖火车票,100个人来买票,每个窗口排10个左右,这个卖票的时间是不是就大大的减少了呢,但是也并不是线程越多就越好,假如来了1000个人买票,你觉得火车站会给你开1000个窗口吗
买票的时间长短和窗口有关,但还有售票员人数这个重要因素,所以我才感觉线程并不一定能增加多少效率。
回复
rumlee 2020-09-09
首先你这个问题举的2个例子都有点局限性。你假设的是一堆砖的总量是不变的,但是实际问题中,可能是有其他机构在生产转,砖头的数量是在不断变化的。 那这种情况就不同了 1、如果是多核的情况下,那就是多个人(取决于多少核)搬多堆砖 2、单核情况下,就是你说的一个人搬3堆砖,搬砖就相当于消耗cpu,可能一堆砖搬完了(需要等待制砖机构送过来),那就可以利用这个时间去搬另外的一堆砖,那这个等待的过程中相当于程序等待IO的过程。 多线程的各种应用场景是复杂的,你不能这么简单的理解问题。 像我们以前的电脑(单核),我们可以一边听着音乐,一边用着打字软件打字,两个程序完全可以并行工作,互相不受影响。那这就是一个人搬了2堆砖,cpu将工作时间分成很小的片段,在多个任务之间切换。就像1个人,疯狂在两堆砖之间跑来跑去,这边搬2块,那边搬2块,满足2个施工工人的砖头需要,只要他搬得足够快,能够完全同时满足2个施工工人的进度,那我们根本就不用关系到底是1个人在搬还是2个人在搬。
回复
div_java 2020-09-08
线程的最大数量不等于cpu的核数,你可以给程序创建100个线程去执行任务,或者更多,但是每个线程都会占用cpu的处理能力,所以cpu性能越强大,理论线程的最大数量就会越多,当然也要考虑内存的关系,每一个线程的栈也需要占用一定的内存。 你创建了三堆砖,如果联想到实际,那么这三堆砖必然要在三个仓库,一个人怎么可能同时去搬三堆砖呢,一次只能搬一个堆中的砖,当然他可以轮换着,一个堆搬一点,不是搬完一堆再搬下一堆,这是逻辑设计的问题了。
回复
你举得例子不够生动形象,其实都是面向对象,例如火车站只有一个窗口再卖火车票,100个人买要排100个人的长队,这可以看做一个线程,火车站有10个窗口在卖火车票,100个人来买票,每个窗口排10个左右,这个卖票的时间是不是就大大的减少了呢,但是也并不是线程越多就越好,假如来了1000个人买票,你觉得火车站会给你开1000个窗口吗
回复
horley208 2020-09-07
没有把3堆砖分配给线程吧?
回复
冰思雨 2020-09-07
刚才看到楼主前面的回复,提到了CPU的核心数这个名词。 现在,打算聊一聊。因为还有一个超线程技术混在里面,比较麻烦。 超线程技术,就像是一个虚拟技术,把一个核心当两个来使用,当然,由于真实的核心数没有增加,那么效率就不是双倍的,好像效率只提高了30%左右吧。 这个技术是从硬件上面来实现的,不用软件开发人员来过多的关注具体的实现细节,只要知道有这么回事儿就可以了。 那么,问题来了。4核8线程的CPU,多线程的程序,上几个线程比较合适? 既然谈到了CPU,那么我们说的多线程程序,就是做CPU密集型运算的,最多上8个线程,把CPU飚满,然后,整个系统卡的一逼,CPU已经没有额外的能力处理键鼠和显示等功能了。那么,上4个是不是就可以了?这玩意,没有什么不可以的,上满8个不也就提升30%的计算能力么,关键是看你对程序的要求叻,有的人觉得CPU飚满了,太卡,觉得程序有问题,有的人呢,觉得CPU都没飚满,任务进展就慢,CPU没有全都用上,程序没有尽可能的利用CPU。 服务器上面的程序,CPU密集型的任务,线程数是要上那个大的,目的就是要尽可能的使用计算机资源。 IO密集型的任务,线程数上多少个,与CPU的核心数没有多大关系,有的时候,线程少了,有些任务得不到执行的机会,当然,太多呢,操作系统有时候带不动。你看看你自己的电脑,是不是开机以后,系统就已经有两千个左右的线程在跑了,你要是写个程序在上个两三千个线程,那么,你觉得操作系统还会依然流畅吗,过犹不及吧,根据自己的使用经验,调整一个合适的值就好。服务器还是很给力的,我说的基本上都是个人PC机上的情况。
回复
qybao 2020-09-07
引用 9 楼 qq_16774199 的回复:
谢谢回复。cpu广告说这个CPU有8核心,是不是说最多允许8个人同时搬8堆砖头?超过8堆砖头,实际上也只能这搬一点那搬一点?

是否是这搬一点那搬一点,取决于你怎么控制线程。如果完全依赖cpu的随机性来调度,那就是这搬一点那搬一点;如果自己做好线程同步控制,就可以这堆搬完再搬下一堆。
回复
qq_39936465 2020-09-07
引用 9 楼 qq_16774199 的回复:
谢谢回复。cpu广告说这个CPU有8核心,是不是说最多允许8个人同时搬8堆砖头?超过8堆砖头,实际上也只能这搬一点那搬一点?
你可以这样理解,如果cpu是8核的话,如果8个人以上的话,也相当于8个人在搬砖,这是硬件条件的限制,当然这里理想情况,现实中效率可能还达不到,毕竟系统不可能只给你一个程序全部占用,但是多线程相对单线程来说可以算是充分利用了硬件资源。你的设备硬件资源越多的话多线程的效率相对越高。
回复
冰思雨 2020-09-07
实际经验中,多线程技术主要用来解决两类问题: 1. CPU密集型任务——比如视频转码,高压缩比的压缩解压,卷积神经网络运算等等; 2. 同步阻塞型任务——比如传统的数据访问,传统的分布式缓存的访问等等。 下面分析楼主的比喻: 1. 在 CPU密集型任务的场景下: 1). 三个线程分别压缩不同的三个文件,每个线程压缩一个文件。很明显,每个线程干的事情是相互独立的,编程复杂度会降低很多。每个线程会分配到一个CPU核心进行运算,如果主机的CPU的核心数大于3个,那么,速度将达到最高;如果主机的核心数小于3个,CPU会满载(其实是过载),机器会非常卡,但是,由于采用了多线程技术,你的压缩任务的进程,会有3次使用CPU时间片的机会,比单一线程的进程,拥有3倍的CPU时间片可用。这就是多线程的典型使用场景。明白了吗? 2). 一个线程压缩三个不同的文件,可以压缩完一个再压缩一个,也可以把文件拆分成多个Segment,然后,三个文件的Segment轮流进行处理,这样的话,每个文件都会有进展。然并卵。这样做和一个压缩完在压缩一个的效率,其实差不多,编程复杂度反而增加了。在CPU满载的情况下还抢不过采用多线程技术的进程。 2. 在同步阻塞型任务的场景下:(Java的BIO技术) 这种场景下,其实没有必要比较3人搬3堆砖还是1人搬3堆砖的问题,因为,这种场景下使用多线程技术,主要是因为编程复杂度相对较低,换句话说,就是程序好往出写,每一个步骤,要么没干完卡死在那儿等着,要么干完了马上就会有结果,然后,一步一步的,就把整个任务完成了。 当然,一般情况下,这种场景,采用多线程的执行效率要远大于单一线程的执行,因为每个步骤都有可能把线程阻塞,线程就干等着啥也不干了。这只是一般情况下,如果,三个线程读取三个大文件,三个文件在同一块硬盘上面,那么,(读取)效率只会比单一线程高那么一点点而已。 最后,分析一下楼主的代码。 很显然,楼主的这段代码是IO密集型任务,控制台输出信息的时候(也就是调用print函数的时候)线程有可能会被阻塞,从而发生线程切换。 为什么说有可能呢?因为,几乎所有的IO操作,都会配备一个缓冲区,当缓冲区写满的时候,数据才会被 flush 到对端。 所以,线程的切换,取决于缓冲区的刷新策略和大小。 楼主的3个线程,都在争抢同一个IO(控制台输出),就像三个线程读取同一块硬盘上的大文件一样,最终的执行效率和单一线程差不多的,因为,相同的IO产生了瓶颈。而执行结果嘛,由于控制台输出采用了缓冲区技术,运行的结果就好像一个线程这边干一点,那边干一点,断断续续的。 楼主要是想把测试现象变得明显一点,那么,不妨每次调用 print 方法之后,紧跟着调用一下 flush 方法,将缓冲区的数据刷新出去,就像冲马桶一样。 That's All .
回复
KeepSayingNo 2020-09-07
你把线程当人看,肯定是第一种解释,你写的代码也诠释了有3个任务,实例化了三个线程分别取处理
回复
SilentHunter460 2020-09-07
引用 8 楼 qq_39936465 的回复:
首先程序并不能脱离操作系统,任何程序都要受到操作系统的硬件限制,多线程程序理想的运行状态其实对操作系统的来说要求是很高的,当你的线程数量远大于系统的cpu核数时,必然会造成看似多线程的程序其实只是在按次序顺序运行,这就是硬件条件达不到软件要求,所以多线程现在还达不到倍数的效率提升,倍数的效率提升只是处于最理想的状态。但是少量提升还是有的,当然你还可以通过分布式服务器来扩展硬件条件来达到软件运行所需的要求。 简而言之,其实目前的民用计算机的硬件条件还达不到随心所欲的使用多线程技术。但是科技是会发展的,就个人看法多线程技术还是很有发展前景的。
谢谢回复。cpu广告说这个CPU有8核心,是不是说最多允许8个人同时搬8堆砖头?超过8堆砖头,实际上也只能这搬一点那搬一点?
回复
qq_39936465 2020-09-07
引用 楼主 qq_16774199 的回复:
多线程的是什么意思: 1)3个人同时搬3堆砖头。 2)1个人同时搬3堆砖头,这堆砖头还没搬完就去搬另一堆。如果是这种的话有什么意义?
首先程序并不能脱离操作系统,任何程序都要受到操作系统的硬件限制,多线程程序理想的运行状态其实对操作系统的来说要求是很高的,当你的线程数量远大于系统的cpu核数时,必然会造成看似多线程的程序其实只是在按次序顺序运行,这就是硬件条件达不到软件要求,所以多线程现在还达不到倍数的效率提升,倍数的效率提升只是处于最理想的状态。但是少量提升还是有的,当然你还可以通过分布式服务器来扩展硬件条件来达到软件运行所需的要求。 简而言之,其实目前的民用计算机的硬件条件还达不到随心所欲的使用多线程技术。但是科技是会发展的,就个人看法多线程技术还是很有发展前景的。
回复
zc08318080 2020-09-07
我就是混个积分的 太难了
回复
ljhhh7890 2020-09-07
多线程是三个人同时搬一堆砖。
1个人同时搬3堆砖是分时系统。
回复
多线程就是多个线程依次占用cpu的使用权。
回复
加载更多回复
相关推荐
发帖
Java SE
创建于2007-09-28

6.2w

社区成员

Java 2 Standard Edition
申请成为版主
帖子事件
创建了帖子
2020-09-06 02:52
社区公告
暂无公告