标签:同步 逻辑 rmi nat stl orm 获取 调度 结果
一个进程有多个线程
进程之间相互隔离,线程之间可以相互通信
cpu一个时间点只能执行一个线程,但多个线程之间的切换比较快,给人一种多个线程同时执行的错觉
继承Thread类(不推荐)
创建类,继承Thread类
重写run()方法
创建对象,使用start()方法启动线程
Java有单继承的局限性,尽量不使用这种方法
实现Runnable接口(推荐使用)
创建类,实现Runnable接口
重写run()方法
创建对象,并将其作为Thread类的构造参数,创建Thread类,调用start()方法启动线程
这种方法避免使用继承,缓解了Java单继承的局限性,并且使用静态代理,可以节约资源
使用到了静态代理,一个资源(对象),多次代理(Thread类代理、多个线程使用一个对象)
实现Callable接口(投入工作后会使用到,前期不使用)
准备状态:当new一个线程(new Thread())时,进入准备状态
就绪状态
事件1:线程调用start()方法,启动线程,进入就绪状态,开始和其他线程抢占cpu资源
运行状态
事件2:通过调度算法,线程被cpu调度,获取到cpu资源,进程线程内的逻辑操作,进入运行状态
阻塞状态
事件3:线程调用sleep、wait方法或者同步锁定时,当前线程进入阻塞状态
事件4:阻塞时间结束后,则重新进入准备就绪状态,开始抢占cpu资源
终止(死亡)状态
事件5:线程被停止、线程逻辑操作执行完毕等事件发生后,线程进入终止状态
一旦进入死亡状态的线程将不能被再次启动
线程停止
不建议使用stop()、destory()等方法,容易造成为止的错误
建议设置一个Boolean值进行控制,要停止线程时,就将其切换为false
线程礼让
yield(),线程调用该方法后进入就绪状态,重新和其他线程抢占cpu
线程休眠
sleep(),线程调用该方法后进入阻塞状态,过了设定的时间后,进入继续状态,和其他线程抢占cpu
线程强制执行
join(),线程调用该方法后立即进入运行状态,之前正在运行的线程进入阻塞状态
使用Thread.getState()来获取该线程的状态
线程状态有几个常量
NEW:尚未启动的线程处于此状态[刚new出来的线程]
RUNNABLE:在Java虚拟机中执行的线程处于此状态[调用start()方法后的线程]
BLOCKED:被阻塞等待监视器锁定的线程处于此状态
WAITING:正在等待另一个线程执行特定动作的线程处于此状态
TIME_WAITING:正在等待另一个线程执行动作达到指定等待时间的线程处于此状态[调用了sleep的线程]
TERMINATED:已退出的线程处于此状态
getPriority、setPriority分别用来获得和设置线程的优先级
线程优先级的范围在1-10,MIN_PRIORITY=1, MAX_PRIORITY=10, (默认优先级)NORM_PRIORITY=5
设置优先级要在线程start之前设置,不然无效
优先级高的不一定先执行,只是被执行的概率更高,同时这会引发一个性能倒置的问题
Java虚拟机只需要保证执行完用户线程(非守护线程)
setDaemon(true),即可使该线程成为守护线程,默认为false
多个线程操作同一个资源,会导致一些不安全的事件发生。例如,银行取钱,两个人同时取一个银行卡的钱,两人取钱的总额大于银行卡余额,结果余额就会出现负数。这就是一种严重的错误。
所以我们要用到锁和队列
当一个线程操作一个资源的时候,给他一个锁,这样来防止同一时间有其他线程来操作这个资源。在使用过资源后,释放锁,交由下一个线程。也就形成了一个队列。
使用synchronized关键字
每个对象都有一把锁
对方法加锁
public synchronized void method(){
逻辑代码
}
这样就实现对方法加锁,在线程调用这个方法的时候,就会默认使用this对象(线程对象)来加锁
代码块加锁
@Override
public void run(){
synchronized (一个对象,一般使用被操作的资源){
逻辑代码
}
}
当运行到代码块时,括号里的对象将会被锁上,逻辑代码执行完之前,其他线程不能访问
使用Lock(接口)锁
ReentrantLock类实现了Lock接口
使用方法
class testLock implements Runnable{
private final ReentrantLock lock =
new ReentrantLock();
@Override
public void run() {
while(true){
try {
lock.lock();//加锁
逻辑代码
}finally {
lock.unlock();//解锁
}
}
synchronized与Lock的区别,前者是隐性的上锁开锁,在进入被其修饰的代码时自动上锁,在跳出代码块后自动解锁
而Lock则是需要手动的上锁解锁,是显性的
两个线程在分别已经拥有一个对象锁并且未解锁的情况下,互相请求获取对方的对象锁,就会造成死锁
例如:小明拿着玩具1,小红拿着玩具2,两人想要对方的玩具的同时,还不想放弃自己的玩具。两人就会僵持住(死锁)
wait()方法:this.wait,会释放锁,所以一般都是使用的同一个对象
notifyAll():通知所有wait的线程启动
标签:同步 逻辑 rmi nat stl orm 获取 调度 结果
原文地址:https://www.cnblogs.com/qingshiJava/p/13718977.html