java.util.concurrent 在并发编程中使用的工具类。
进程: 后台运行的每一个程序就是一个进程,是一个正在执行的程序。比如用QQ音乐放音乐,同时用QQ聊天,每一个都是一个进程。
线程: 线程是进程中的一个独立的控制单元,一个进程中至少包含一个线程。比如,我们使用Idea写代码的同时,idea可以进行一些语法检查,这就是idea的一些线程。
更为形象的例子:
一个正在运行的软件(如迅雷)就是一个进程,一个进程可以同时运行多个任务( 迅雷软件可以同时下载多个文件,每个下载任务就是一个线程), 可以简单的认为进程是线程的集合。
1、Java程序在执行的时候默认是有两个线程的,一个是负责java程序执行的main线程,也叫主线程,另一个是负责垃圾回收机制的GC线程。
2、Java是开不了线程的,因为Java是运行在虚拟机之上的,无法直接操作硬件。通过本地方法(private native void start0())去调底层的C++。
并发:同一时刻多个线程操作同一资源。比如春运抢票,电商秒杀等。
对于单核CPU来说,某一时刻只能有一个线程运在行,多个线程间快速切换,形成一种并发的效果。线程是谁抢到谁执行,执行多长时间也是由CPU说了算。
并行: 多项工作同时执行。
只有在CPU多核的情况下,多个线程才可以同时执行。
public class Test {
public static void main(String[] args) {
// 获取cpu的核数
// CPU 密集型,IO密集型
System.out.println(Runtime.getRuntime().availableProcessors());
}
}
总结:
并发:单核CPU,模拟出多条线程,CPU快速轮流执行。
并行:多核CPU,开启多条线程,CPU同时执行。
多线程的好处:可以充分利用CPU的资源
1、可以同时并发执行多个任务。
2、最大限度的降低CPU的闲置时间,从而提高CPU的利用率。
比如饭店做饭的例子,厨师炒菜需要半小时,煮面需要半小时,如果饭店只有一个厨师,炒好菜后然后煮面,那么做好饭的时间就是一个小时,客人会等不急,这样肯定是不行的。如果饭店有2个厨师,一个厨师负责炒菜,另一个厨师负责煮面,只需要半个小时就可以做好饭。如果把每个厨师看做一个线程,多个厨师即多线程,就可以提高工作的效率。
顺序编程:程序从上往下的同步执行,即如果第一行代码执行没有结束,第二行代码就只能等待第一行执行结束后才能结束。
public class OrderProgramma {
public static void main(String[] args) throws Exception {
// 顺序编程:先炒菜再煮面
cooking();
noodles();
}
private static void cooking() throws Exception {
System.out.println("开始炒菜...\t" + new Date());
Thread.sleep(5000);
System.out.println("结束炒菜...\t" + new Date());
}
private static void noodles() throws Exception {
System.out.println("开始煮面...\t" + new Date());
Thread.sleep(5000);
System.out.println("结束煮面...\t" + new Date());
}
}
可以看出,顺序编程,先炒菜后煮面,总共耗时10秒。
并发编程:多个任务可以同时做,任务与任务之间比较独立,互不影响。
public class ThreadProgramma {
public static void main(String[] args) {
// 多线程编程:一边炒菜一边煮面
new Cooking().start();
new Noodles().start();
}
static class Cooking extends Thread {
@Override
public void run() {
System.out.println("开始炒菜...\t" + new Date());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束炒菜...\t" + new Date());
}
}
static class Noodles extends Thread {
@Override
public void run() {
System.out.println("开始煮面...\t" + new Date());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束煮面...\t" + new Date());
}
}
}
可以看到,并发编程,一边炒菜一边煮面总共用时5秒,比顺序编程更快,因为并发编程可以同时运行,而不必等前面的代码运行完之后才允许后面的代码。
同一个时刻一个CPU只能做一件事情,即同一时刻只能一个线程中的部分代码,假如有两个线程,Thread-0和Thread-1,刚开始CPU说Thread-0你先执行,给你3毫秒时间,Thread-0执行了3毫秒时间,但是没有执行完,此时CPU会暂停Thread-0执行并记录Thread-0执行到哪行代码了,当时的变量的值是多少,然后CPU说Thread-1你可以执行了,给你2毫秒的时间,Thread-1执行了2毫秒也没执行完,此时CPU会暂停Thread-1执行并记录Thread-1执行到哪行代码了,当时的变量的值是多少,此时CPU又说Thread-0又该你,这次我给你5毫秒时间,去执行吧,此时CPU就找出上次Thread-0线程执行到哪行代码了,当时的变量值是多少,然后接着上次继续执行,结果用了2毫秒就Thread-0就执行完了,就终止了,然后CPU说Thread-1又轮到你,这次给你4毫秒,同样CPU也会先找出上次Thread-1线程执行到哪行代码了,当时的变量值是多少,然后接着上次继续开始执行,结果Thread-1在4毫秒内也执行结束了,Thread-1也结束了终止了。CPU在来回改变线程的执行机会称之为线程上下文切换。
1、线程需要占用内存,线程越多占用的内存也就越多。
2、高并发问题
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_44075963/article/details/113488031
内容来源于网络,如有侵权,请联系作者删除!