Java多线程
1、线程和进程
进程是一个应用程序。例:公司
线程是进程的一个执行场景。例:某个员工
一个进程可以执行多个线程(公司有多个员工)。
进程之间内存独立不共享;线程之间共享堆内存和方法区内存,栈内存是独立的。
attention:
1、启动一个Java程序之后:会先驱动JVM(进程),同时:垃圾回收线程、main方法的主线程
2、单核CPU无法实现真正意义上的多线程,这些线程只能交替进行,抢夺cpu时间片的使用权,从而有一种多线程的假象。
3、main方法结束,是否代表程序运行结束? 不一定。main方法的线程结束,其他县城可能还在工作,此时程序不一定运行结束。
4、Java为什么要实现多线程的作用/好处:提高执行效率。
2、两种实现多线程方式
2.1方法一:编写()类继承java.lang.Thread,重写run方法
run方法里写要实现分支线程的代码;
之后新建分支线程对象luhan类并启动start方法;
start方法运行时,JVM会自动开辟新的栈,就开启了分支线程;会自动调用run方法,此时run方法在分支线程中运行。
注意如果此时直接通过对象调用run方法,没那么还是在主线程中进行的run方法
2.2 方法二:编写()类实现java.lang.runnable接口并且重写run方法
这种方式使用的频率更高,编写起来更加方便
因为是实现接口,所以可以继承其他的类,更加灵活。
还有一种匿名内部类的方式,直接使用匿名内部类然后重写run方法。
start和run方法
3、线程的生命周期
操作系统基础知识,略
初始态、就绪态、运行态、阻塞态、终结态
4、 线程名字
get set方法
5、线程的一些方法
5.1 sleep
使当前线程进入休眠状态。成为阻塞态,放弃占有时间片的机会,让给其他线程使用;
sleep() 参数是以毫秒为计量单位;
作用:间隔特定时间执行一段代码
题:
不会,此方法在main线程中进行,会让main线程休眠5秒,不会rangt线程休眠,。
5.2 interrupt
使正在休眠(sleep)的线程终止休眠;
5.3 终止线程的方法
方法一:使用stop方法直接强行终止
强行让他退出;可能会导致数据丢失,不建议使用。
方法二:合理的方法
加上一个if块,设置一个布尔参数,需要终止时设为false;
else块中可以加上保存数据等代码。
6、线程的调度问题
常见的线程调度模型:
抢占式:优先级高,时间片多
均分式:平均分配CPU时间片
线程调度的方法:
- setPriority 设置线程的优先级
- getPriority 获取线程的优先级
最低优先级1
默认优先级是5
最高优先级是10
优先级高的线程获取时间片可能会多一些,但是不是绝对的。
3.yield 暂停当前线程,并执行其它线程 。但是随时可能会抢回来继续执行。
4.join() 合并线程
7、线程安全(重要)
排队执行来解决线程并发带来的线程安全问题—叫做线程同步机制。线程排队会牺牲一些效率;
7.1使用synchronized关键字
共享对象有对象锁
实例方法使用synchronized 关键字,
优点:代码简洁】
如果共享的对象是this,或者整个方法体就是要同步的方法体时,使用synchronized
**
**
synchronized总结:
第三种:在静态方法上使用synchronized,表示找类锁,
7.2 死锁
两个线程互相等待对方释放对象,无法继续执行;不出现异常,也不报错,程序僵持无法结束。
要学会写死锁
7.3 如何避免或者解决线程安全问题
1、 synchronized会让程序的执行效率降低,用户体验不好;系统的用户吞吐量变低;不到万不得已不选择线程同步机制。
2、尽量使用局部变量代替“实例变量和静态变量”
3、若必须使用实例变量,考虑创建多个对象,避免实例变量共享内存,一个线程对应一个对象;多个线程对应多个对象,减少数据安全问题。
4、若不能使用局部变量,且不能创建多个对象;此时只能用线程同步机制,选择synchronized