目录:
为什么要有多线程呢?
多线程的两个概念
多线程的实现方式
常见的成员方法
线程安全的问题
死锁
生产者和消费者
一、为什么要有多线程呢?
1.1 线程
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
1.2 进程
进程是程序的基本执行实体。
一个软件运行之后就是进程。
当互相独立的,能同事运行的功能比较多就是多线程。
例子:
从负责一个流水线到负责三个,工作效率提高了。
内存中创建变量也需要时间。在此期间,CPU只能等待。
单线程:从头往下依次执行。CPU不会切换到其他代码去运行,所以效率比较低。
多线程的特点:同时的做多件事情。CPU可以在多个程序之间切换,把等待的空闲时间充分利用。最大特点:提高程序的运行效率。
多线程的应用场景
方法多开与多个线程同时处理一个内存数据的故事。
总结
1.什么是多线程?
有了多线程,我们就可以让程序同时做多件事情
2.多线程的作用?
提高效率,利用程序运行当中的等待时间,让CPU在多个程序间进行切换。从而提高程序的运行效率。
3.多线程的应用场景?
只要你想让多个事情同时运行就需要用到多线程
比如:软件中的耗时操作、所有的聊天软件、所有的服务器
二、多线程的两个概念
并发:在同一时刻,有多个指令在单个CPU上交替执行。
并行:在同一时刻,有多个指令在多个CPU上同时执行。
右手拿鼠标、🚬、可乐交替执行,就是并发。
电脑不就一个CPU吗?但是一个CPU有:
这里的4、8、16、32、64就表示电脑能够同时运行多少条线程。
以2核4线程为例:
当计算机中只有四个线程是不用切换的。
当线程越累越多,这4条线程就会在多个线程之间随机切换。
所以,在计算机当中,并行和并发是有可能同时发生的。
总结
1.并发:在同一时刻,有多个指令在单个CPU上交替执行
2.并行:在同一时刻,有多个指令在多个CPU上同时执行
三、多线程的实现方式
①继承Thread类的方式进行实现
Thread就表示Java中的一个线程,如果想拥有一个线程,就创建对象,并开启即可。
例子:
创建两个线程:t1、t2。如果不起名称,他俩执行时没有区别,无法显示,所以就setName,执行时getName()即可。
是两个线程交替执行的。
②实现Runnable接口的方式进行实现
这里不能直接使用getName方法进行获取线程名字,因为getName()是Thread类中的方法,MyThread直接调用父类的getName()方法。而现在的MyRun没有继承,所以没有getName()。
可以先获取到线程,再getName():
和刚刚的一样:
③利用Callable接口和Future接口方式实现
前两种的重写Run方法,没有返回值,无法知晓多线程运行的结果。
Future是一个接口不能直接创建对象,所以创建一个实现类FutureTask的对象。
这里的范型,表示返回结果的类型:
然后再重写抽象方法,call方法返回值和范型保持一致。
获取结果:FutureTask.get()即可,抛出异常。
总结
多线程三种实现方式对比
Java中是单继承。
四、常见的成员方法
线程优先级默认是5,最小是1,最大是10.
优先级越大,抢占的CPU的概率是越高的。
守护线程:备胎线程。
join不是静态方法。
细节
默认线程是否有名字:
源码:
线程细节:
构造方法不能继承,所以子类MyThread不能使用父类Thread的构造方法.
优先级?调度?
说到线程优先级,那就必须说到调度。
1.抢占式调度
多个线程抢夺CPU的执行权。CPU在什么时候执行那条线程是不确定的,执行时长也是不确定的。体现了——随机性。
2.非抢占式调度
所有的线程轮流执行,执行时间也是差不多的。你一次、我一次。
在Java中是采用抢占式调度的方式。
没有设置优先级,默认是5。
JVM中启动的main线程的优先级也是5.
ctrl+f12:查看当前.java的所有方法。
优先级并不是绝对的,而是概率问题。
守护线程Daemon
守护线程应用场景?
当关闭聊天,传输文件也没有执行下去的必要了,设置为守护线程也会慢慢停掉。