javaSE复习之——线程
Posted lijianming180
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaSE复习之——线程相关的知识,希望对你有一定的参考价值。
线程其实就是程序执行的一条路径,一个进程中可以包含多条线程,多线程并发执行可以提高程序效率,可以同使完成多项任务
多线程的应用场景
- 迅雷多线程一起下载
- 服务器同时处理多个客户请求
多线程原理(单核CPU)
在电脑上运行多个程序时,其实cpu一次只能做一个事,做一段时间后然后换另一个另一个做一段时间,只是cpu的速度太快了,
看起来就是同时做很多事
,也就是说多线程其实只是表面上的多线程
,底层cpu还是一次只能做一个事,但是这有个前提,那就是那个cpu是单核cpu,如果事多核cpu,那么就可以真正的达到并行
。
多线程并行和并发的区别
- 并行
并行是两个任务同时运行,需要多核cpu,有多少核就可以并行多少任务。
- 并发
并发是两个任务都请求运行,而一个处理器只能接受一个任务,就安排两个任务轮流进行,由于时间比较段短就感觉两个任务是同时在运行
- ps
我们所谓的多线程就是并发,如果不使用多线程,那么程序就是一句一句代码请求,如果使用了多线程,那么就可以这个方法请求运行,同时另一个方法也请求运行,也就是说,
没有使用多线程的话代码是一条一条请求,使用了就是多条同时请求,但底层并不是并行
,只是cpu处理太快了感觉不到。
多线程程序实现方法1
1、定义类继承Thread
2、重写run方法
3、把新线程要做的事写在run方法中
4、创建线程对象,也就是我们定义的这个对象
5、开启新的线程(start),内部会自动执行run方法
多线程程序实现方法2
1、定义类实现Runnable接口
2、重写run方法
3、把新线程要做的事卸载run方法中
4、创建Thread对象,并且给它的构造方法传入一个实现了Runnable接口类的对象
5、利用Thread开启新的线程
多线程程序实现方法3
第三种创建多线程的接口
Callable
创建方式:
1、创建一个线程类,并且继承Callable<>类和重写call方法
2、创建线程池
3、创建线程对象然后用submit方法加入线程池即可
两种实现多线程的区别(面试可能问)
继承Thread:
因为我们创建的类继承了Thread类,所以当我们调用start时,是直接执行子类的run方法,也就是我们创建的类。
实现Runnable接口创建对象并传入实例化Thread的构造方法:
我们是先创建实现了Runnable接口的对象,然后创建Thread对象并把之前创建的对象传入Thread构造方法,这时Thread类会把传入的对象保存到成员变量中,当我们调用Thread对象的start方法的时候,Thread对象会调用它的成员变量中的run方法,当然这个成员变量就是我们创建的那个实现了Runnable接口的对象
两种实现多线程的好处与坏处
继承Thread:
好处:
可以直接调用Thread中的方法,这样代码简洁。坏处:
既然继承了Thread方法就不能继承其他类了
实现Runnable接口:
好处:
因为接口是可以多实现的,所以可以继承其他父类坏处:
不能直接创建对象使用,代码更加复杂
ps:
个人感觉实现Runnable其实是继承Thread的一个补充,在开发时看情况使用。
Thread类的方法
- .start()
开启线程,多次启动是非法的
- .getName()
获取线程名,默认线程名从Thread -0开始以此类推
- .setName()
设置线程名
- .c 大专栏 javaSE复习之——线程urrentThread()
获取当前线程对象的引用,在哪调用就获取哪的线程
- .sleep(毫秒, 纳秒)
休眠线程,传入多少时间就停多长时间,也可以单独传毫秒
.setDaemon()
守护线程,设置一个线程为守护线程后,该线程不会单独执行,当其他非守护线程全部执行完之后自动退出。
- ps:
在非守护线程全部执行完毕后,会有一个缓冲时间,这个缓冲时间内守护线程还会运行,也就相当于非守护线程退出时会告诉守护线程可以退出了,这个告诉的时间就是缓冲时间
- ps:
.join()
调用此方法的线程暂停(写这句代码的线程),等待指定线程结束后,当前线程再继续运行
.join(int)
等待指定的毫秒后继续执行
- ps:
如果在main主方法中调用t.join(),那么等待t这个线程执行结束之后,主方法才会继续执行,这个命令通常用在主方法中。
- ps:
.yield()
礼让线程,让出cpu,也就是让自己在cpu的执行优先级中降低,就是让别人先执行
- .setPriority(1-10)
设置线程优先级,默认是5
- .getThreadGroup()
通过线程对象获取它所属的组,返回线程组对象
同步代码块的概述
当有多条线程并发的时候,cpu会先执行完
同步代码块
中所有代码才会去执行另一个线程,不会这里执行几句代码那里执行几句代码
。
- ps:
它其实就是锁
什么时候需要同步?
当多线程并发,我们希望某个线程中某些代码执行过程中不切换到其他线程工作,我们就需要用到同步代码块。
同步代码块关键字
synchronized
定义方式:
1 | (锁对象) { |
同步代码块(锁)的注意事项:
1、锁对象可以是任意的对象
2、两个需要同步的代码块需要使用同一个锁,否则不能达到目标效果
3、不能是匿名对象,因为两个匿名对象根本就不是一个对象,也就是不是同一把锁
4、不要把锁进行嵌套,否则容易出现死锁,因为可能会出现互相等待的局面
同步方法如何定义?
- 解答:
只要在修饰方法的时候加上synchronized关键字即可
同步方法注意事项:
- 非静态方法锁对象是
它自己这个对象
,也就是this - 静态方法因为它是随着类的加载而加载的,所以它的对象就是它所在类的
字节码文件
,也就是说静态方法的锁对象就是它所在类的字节码文件
线程安全问题
当多条线程操作同一个数据时,可能会出现数据安全问题
解决方法
在某一段需要判断并且操作数据地方加上一个同步代码块
注意事项
使用的锁对象一定要是同一个锁,
建议直接用类的class文件
,如果非要用引用数据类型,那么一定要用静态的。
以前线程安全类的回顾
线程安全的类涉及数据操作的方法都加了synchronized修饰,比如Vector、ArrayList,StringBuffer、StringBuilde
线程安全方法
.synchronized[这里可以后接集合类型,是什么类型就返回那个类型的集合]
- ps:
它的作用是传入一个集合对象,传出一个线程安全的集合对象
以上是关于javaSE复习之——线程的主要内容,如果未能解决你的问题,请参考以下文章