线程状态
- new 尚未启动的线程
- RUNNABLE 在Java虚拟机中执行的线程处于次状态
- BLOCKED 被阻塞等待监视器锁定的线程处于此状态
- WAITING 正在等待另一个线程执行特定动作的线程处于此状态
- TIMED_WAITING 正在等待另一个线程执行动作达到指定等待时间的线程处于次状态
- TERMINATED 已退出的线程处于次状态
public class Demo12 {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("子线程结束");
});
Thread.State state = thread.getState();
System.out.println(state);
//开启子线程
thread.start();
state = thread.getState();
System.out.println(state);
//只要不终止,在主线程一直输出子线程状态
while( state != Thread.State.TERMINATED){
Thread.sleep(100);
state = thread.getState();
System.out.println(state);
}
}
}
线程优先级
-
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程, 线程调度器按照优先级决定应该调度哪个线程来执行
-
线程的优先级用数字表示,范围从1~10
- Thread.MIN_PRIORITY =1;
- Thread.MAX_PRIORITY =10;
- Thread.NORM_PRIORITY =5;
-
getPriority()获取优先级
-
setPriority() 改变优先级
-
优先级低只是意味着获得调度的概率低 并不是优先级低就不会被调用了 这都是看CPU的调度
package com.wu.thread;
public class Demon13 {
static class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"->" + Thread.currentThread().getPriority());
}
}
public static void main(String[] args) {
MyPriority myPriority = new MyPriority();
Thread t1 = new Thread(myPriority);
Thread t2 = new Thread(myPriority);
Thread t3 = new Thread(myPriority);
Thread t4 = new Thread(myPriority);
//输出主线程默认优先级
System.out.println(Thread.currentThread().getName() + "->" + Thread.currentThread().getPriority());
//输出子线程默认优先级
t1.start();
//改变子线程优先级
t2.setPriority(Thread.MIN_PRIORITY);
t2.start();
t3.setPriority(7);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY);
t4.start();
}
}
守护(daemon)进程
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
- 守护进程: 后台记录操作日志 监控内存 垃圾回收等
- 创建守护进程 new Thread.daemon(true);
线程同步
-
多个线程操作同一个资源
-
并发 同一个对象被多个线程同时操作
-
队列和锁 解决并发问题
-
由于同一进程的多个线程共享同一块存储空间 在带来方便的同时 也带来了访问冲突问题 未来保证数据在方法中被访问时的正确性, 在访问时加入锁机制 synchronized 当一个线程获得对象的排它锁 独占资源 其他线程必须等待 使用后释放锁即可.存在一下问题:
- 一个线程持有锁会导致其他所有需要此锁的线程挂起
- 在多线程竞争下 加锁 释放锁会导致比较多的上下文切换 和调度延时 引起性能问题
- 如果一个优先级高的线程等待一个优先级低的线程释放锁 会导致优先级倒置 引起性能问题
-
同步方法:synchronized方法和synchronized{Obj}块
-
public synchronized void method();
-
缺陷若将一个大的方法声明为synchronized将会影响效率
package com.wu.thread;
//
public class Demo18 implements Runnable{
private int tickets =10;
private boolean flag =true;
@Override
public void run() {
while(flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
// return;
}
}
private synchronized void buy() throws InterruptedException {
if (tickets <=0){
flag = false;
System.out.println("票已售罄");
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "拿到了第" + tickets-- + "张票");
}
public static void main(String[] args) {
Demo18 demo18 = new Demo18();
new Thread(demo18,"张三").start();
new Thread(demo18,"李四").start();
new Thread(demo18,"黄牛党").start();
}
}