线程状态:
线程状态: 新生状态: new 就绪状态: start()准备好了,进入就绪队列,等待cpu的调度 运行状态: 当cpu调度某一个线程,这个线程获取线程体,执行线程体中的代码 阻塞状态: 线程无法正常执行 终止状态: 线程结束 注意: 一个线程如果一旦进入终止状态无法恢复,new了也是一个新的线程 如果一个线程一旦进入到阻塞状态,阻塞接触会直接恢复到就绪状态不会恢复运行状态 一个线程如何进入到就绪状态: 1.start() 2.阻塞解除 3.yield 礼让线程 4.线程切换 一个线程如何进入到阻塞状态 1.sleep 2.join 插队 3.wait() 一个线程如何进入到终止状态 1.stop() 已过时 2. destory() 已过时 3.通过添加标识判断 Thread.sleep(ms) 线程休眠|睡眠 在休眠时间阻塞范围之内,会让出cpu的资源 抱着资源睡觉: 对象|对象锁 作用: 1.模拟网络延迟 2.方法问题的可能性 注意: run()方法中不能抛出异常,不能定义返回值
礼让线程 :
礼让线程 yield 高风亮节 静态方法 ,让当前线程让出cpu的资源 无法控制cpu是否还会调度到当前线程,方法其他线程执行的可能
public class YieldDemo04 implements Runnable{
public static void main(String[] args) {
new Thread(new YieldDemo04(),"A").start();
new Thread(new YieldDemo04(),"B").start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始了");
Thread.yield(); //礼让
System.out.println(Thread.currentThread().getName()+"结束了");
}
}
join 插队线程 void join() 等待这个线程死亡。 void join(long millis) 此线程最多等待 millis毫秒。
//先就绪再插队
th.start();
try {
th.join(); //线程插队
} catch (InterruptedException e) {
e.printStackTrace();
}
守护线程与用户线程:
定义一个线程默认为用户线程 守护线程是用来守护用户线程的,如果用户线程结束,守护线程会自动结束 垃圾回收器是一个典型的守护线程 设置一个线程从用户线程变为守护线程 setDaemon(boolean on) true->守护 需要在线程开启之前设置守护 interrupt() 为某一个线设置终止标识|状态 isInterrupted() 判断某一个线程是否处于终止状态,判断但是不会清楚线程的终止标识(判断调用方法的线程) interrupted() 判断当前这在运行的线程是否存于终止状态,如果是ture,不是返回false,同时清除终止状态 以上方法只是设置标识,但是不能终止线程,想要终止想成,可以配合设置判断,break|return等结束线程体
//守护线程
th.setDaemon(true);
//判断一个线程是否存活
System.out.println(th.isAlive());
线程优先级:
1~10 默认线程的优先级为5 最小1 最大10 int getPriority() 返回此线程的优先级。 void setPriority(int newPriority) 更改此线程的优先级。 static int MAX_PRIORITY 线程可以拥有的最大优先级。 static int MIN_PRIORITY 线程可以拥有的最低优先级。 static int NORM_PRIORITY 分配给线程的默认优先级。 方法线程先执行的可能 Thread.State getState() 返回此线程的状态。 Thread.State 枚举类 标识线程的所有状态情况 可以根据线程的状态进行判断,控制程序的执行逻辑
th.setPriority(Thread.MAX_PRIORITY);
th.setPriority(Thread.MIN_PRIORITY);
th.setPriority(Thread.NORM_PRIORITY);
线程通信:
使用Object类中的wait() ,notify()实现线程通信 wait() 等待,当一个线程wait()方法的时候回进入到某一个对象的等待池中进行等待,等待被唤醒-->挂起 notify() 唤醒,唤醒该对象等待池中正在等待的线程 wait与notify()和notifyAll()方法必须使用同步环境下 用来作为多线程之间数据协调问题,要使用在同步环境下控制线程安全,否则会抛出异常 wait与sleep之间的区别: wait释放对象的锁,让出cpu的资源 sleep() 抱着资源睡觉,不会释放对象的锁,让出cpu资源
线程安全问题:
线程安全问题: 多线程操作同一份数据的时候,才有可能出现线程不安全的情况 synchronized 同步锁->排它锁 修饰方法:同步方法 synchronized成员方法 synchronized静态方法 修饰块: 同步块 sychronized(this|类的class对象|资源){ 排队执行的代码; } 同步方法比较简单,但是可能同步的代码范围太大,效率较低 推荐使用同步块,同步块可以同步的代码范围范围较小,但是相对比较复杂 注意: 锁()中的内容,要锁不变的东西,自定义的引用数据类型的对象地址肯定不变 代码范围太大效率低,代码范围太小,容易锁不住
同步块-> 锁this: 锁()中的内容,要锁不变的东西,自定义的引用数据类型的对象地址肯定不变 代码范围太大效率低,代码范围太小,容易锁不住 双重检查 double check 提高效率,缩小同步的代码范围,保证数据的安全 锁this,锁住某一个对象,相当于锁住这个对象的所有资源(成员),当只想锁住其中的某一个资源的时候,可以选择只锁这个资源
synchronized (this){ //this->web对象,调用run()方法的对象
...
}
同步块-> 锁类: 锁类相当于锁了这个类的所有对象,当有些有需要对象不需要被锁的时候,可以选择锁this,只锁住某一个对象
synchronized (Web12306_03.class){ //类的class对象,唯一的,独一份的不会变的
...
}
同步块-> 锁资源: