java-线程

线程
1.线程与进程

①. 线程的划分尺度小于进程,线程隶属于某一个进程
②.进程是程序的一种动态形式,是CPU,内存等资源占用的基本单位,
而线程是不能独立的占有这些资源的
③.进程之间相互独立,通信困难,线程之间共享同一块区域,通信方便
④.进程在执行过程中,包含比较固定的入口、执行顺序和出口,而线程的这些
过程会被应用程序所控制。
线程作用:快速同时执行多段代码,执行效率高
线程分类:前台线程(执行线程) main()方法
前台线程不停止,jvm不会关闭
后台线程(守护线程/线程精灵)gc()方法
前台线程全部都销毁,后台线程也会死亡
2.线程的声明周期
①.新建状态(New):用new语句创建的线程对象处于新建状态,此时它和其他Java
对象一样;仅在堆区中被分配了内存;
②. 就绪状态(Runnable):当一个线程对象创建后,其他线程调用它的start()方法,
该线程就进入就绪状态,Java虚拟机会为它创建方法调用栈。
处于这个状态的线程位于可运行池中, 等待获得CPU的使用权。
③. 运行状态(Running):处于这个状态的线程占用CPU,执行程序代码。
在并发运行环境中,如果计算机只有一个CPU,那么任何时刻只会有一个线程处于
这个状态。
如果计算机有多个CPU, 那么同一时刻可以让几个线程占用不同的CPU,使它们
都处于运行状态。
只有处于就绪状态的线程才有机会转到运行状态。
④. 阻塞状态(Blocked):指线程因为某些原因放弃CPU, 暂时停止运行。
当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,
它才有机会转到运行状态。
⑤. 死亡状态(Dead):当线程退出run()方法时,就进入死亡状态,该线程结束生命周期。
正常执行完run()方法退出
遇到异常时退出
不管线程正常结束还是异常结束,都不会对其他线程造成影响。
阻塞状态:代码暂停运行
①.挂起:不释放锁资源,不抢夺cpu执行权限
sleep();:可以指定线程休眠的时间,线程休眠的时间以毫秒为单位
join();:当某个线程使用join()方法加入到另外一个线程时,另一个线程
会等待该线程执行完毕后再继续执行。
yield();:当前线程让出cpu执行权限立刻回到就绪状态
②.锁池等待:
当线程执行有锁的代码时,锁被其他线程获取走了,
当前线程就会到锁池等待。

其他线程执行完毕加锁的代码,就会自动释放锁。
当前线程从锁池回到就绪状态。
③.等待池等待:
sy(){
锁.wait();会释放锁资源,释放cpu执行权限
锁.notifyAll();
回到锁池等待。
t.interrupt();
回到锁池等待。
}
3.线程常用方法
start() 开启线程,线程只能启动一次
sleep() 可以指定线程休眠的时间,线程休眠的时间以毫秒为单位
Thread.sleep(1000);//当前线程睡1000毫秒
(放弃cup执行权限)
currentThread() 获取当前正在执行的线程
getName() 获取线程名
setName(“线程名”); 设置线程名(或者构造器)
join() 优先执行线程
当某个线程使用join()方法加入到另外一个线程时,另一个线程
会等待该线程执行完毕后再继续执行。(放弃cup执行权限)
yield() 当前线程让出cpu执行权限立刻回到就绪状态(放弃cup执行权限)

notify() 随机唤醒一个线程–>等待池
notifyAll() 唤醒所有线程
interrupt() 设置线程中断状态标识位–>中断状态:true
isInterrupted() 查看返回线程的中断状态标识位 true:有线程要中断当前线程
不会清除线程的中断状态
interrupted() 返回线程的中断状态标识位 true:有线程要中断当前线程
清除线程的中断状态
setDaemon(true) 把新建状态的线程设置为守护线程。只能是新建状态。
stop()

sleep()和wait()有什么区别?
sleep()是线程类方法,导致线程暂定执行指定的时间,将执行机会让给其他线程,
不会释放对象的锁
wait()是Object类方法,导致本线程放弃对象锁,只有执行notify或notifyAll
方法后,才能获得对象锁进入就绪再到运行状态

4.线程同步(安全)
原因:多个线程在操纵共享资源(实例变量时),有可能引起共享资源的竞争
解决:引入同步机制,在有可能引起共享资源竞争的代码加上synchronized标记
把处理共同数据的代码锁起来
锁对象需要唯一
synchronized(锁对象){


public synchronized void m()的锁是this
public static synchronized void m()的锁是类.class
注意
①.synchronized(){}拿锁操作是原子操作,只有一个线程能拿到锁,每个java对象
有且只有一个同步锁
②.锁被其他线程占用,虚拟机会把消费者线程放到this指定对象锁池中,线程进入
阻塞状态
③.线程只有执行完同步代码块,才会释放锁
特征
①.同步代码块和非同步代码块同时操纵共享资源,仍会造成对共享资源的竞争
②.每个对象会有唯一同步锁
③.静态方法前面用synchronized修饰时,该同步锁的对象称为类对象
④.当一个线程开始执行同步代码块时,可中断Interrupt()
⑤.synchronized声明不会被继承
编程步骤
①.找出多个线程的共享对象
②.确定临界区:哪些代码在操作上共有data
③.在临界区上方用synchronized拿共享对象的锁,在临界区下方用}释放锁
5.线程通信
方法: Object.wait()阻塞等待,必须获得共享对象的锁
Object.notify()叫醒一个,必须获得共享对象的锁
Object.notifyAll()叫醒所有,必须获得共享对象的锁
注意: wait()与notify()之间必须有共享对象,确保wait()在notify()之前
编程步骤
找到同步线程的共享对象
站到线程内部分析:每个线程单独分析需要wait()还是notify()
控制wait()发生在notify()之前,无固定模式
6.创建线程的方法
①.继承Thread类
start()用于启动线程,去争取CPU时间
run()包含线程运行时所执行的代码
通过继承Thread类来实现线程
1.创建一个继承Thread类的子类;
2.重写Thread类的run()方法;
3.创建线程类的一个对象;
4.通过线程类的对象调用start()方法启动
②.实现Runnable接口
通过实现Runnable接口来实现线程
1.创建Runnable对象;
2.使用参数为Runnable对象的构造方法创建Thread对象;
3.调用start()方法启动线程;
7.线程调度模型
分时调度模型
让所有线程轮流获得CPU的使用权,并且平均分配每个线程占用CPU的时间片
抢占式调度模型
优先级高的线程占用CPU;优先级相同,随机选择线程占用CPU,处于可运行状态
的线程会一直运行直至不得不放弃CPU
8.调整程序优先级
静态常量:MAX_PRIORITY:10,最高;
MIN_PRIORITY:1,最低
NORM_PRIORITY:5,默认优先级
设置获取优先级:
Thread类的setPriority(int)和getPriority()方法分别用来设置和读取
优先级,优先级用整数表示,范围0-10
注意:优先级高的不一定会优先执行,优先级高的线程优先运行的概率大
9.释放对象的锁情况
①.执行完同步代码快
②.执行同步代码块过程中,遇到异常导致线程终止,释放锁
③.执行同步代码块过程中,执行了锁所属对象的wait()方法,释放锁进入对象
的等待池
10.不释放对象锁的情况
Thread.sleep()方法,放弃CPU,进入阻塞状态;
Thread.yield()方法,放弃CPU,进入就绪状态;
11.死锁
指多个线程在运行过程中因争夺资源而造成的一种僵局
原因: 资源竞争 推进顺序不当
避免:
加锁顺序:线程按照一定的顺序加锁
加锁时限:线程尝试获取锁的时候加上一定的时限,超过时限则
放弃对该锁的请求,并释放自己占有的锁
死锁检测

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值