线程的状态
创建状态、就绪状态、阻塞状态、运行状态、死亡状态
线程调度
线程调度是指按照特定机制为多个线程分配CPU的使用权
方法 作用
setPriority(int newPriority) 更改线程的优先级
sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠
join() 强制执行
yield() 线程礼让,给其他线程获得CPU资源的机会
interrupt() 中断线程
isAlive() 测试线程是否处于活动状态
注意:
1、线程优先级高的线程获得CPU资源的概率较大,但不是一定(优先级从低到高:1~10)
2、线程礼让只是提供一种可能,不能保证一定会实现礼让
线程安全的类型
线程安全:方法同步,效率较低,适用多线程并发共享资源
非线程安全:方法不同步,效率高,适用单线程
线程安全类会使用synchronized 修饰方法或代码块
同步方法
语法:访问修饰符 synchronized 返回类型 方法名(参数列表){……}
同步代码块
语法: synchronized (this) { //同步代码块}
案例
模拟网络抢票
1、不使用同步:当第一个线程运行到休眠时第二个线程获得CPU资源对数据进行更改,所以第一个线程休眠结束后输出的结果就改变了,导致同一张票由两个人或三个人同时抢到
public class Piao implements Runnable {
// 声明一个变量用来表示票库中票的数据
public int num = 10;
// 声明一个变量用来表示用户抢到了第几张票
public int count = 0;
@Override
public void run() {
// 实现抢票行为:修改票库里的票的数目和显示用户抢到了第几张票
while (true) {
// 当票库里的票<0的时候,不再进行循环
if (num <= 0) {
break;
}
num--;
count++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了第"
+ count + "张票,还剩下" + num + "张票");
}
}
}
2、同步方法:当第一个线程抢到CPU资源时,整个方法会被锁死,第二个线程进不来必须等待第一个线程运行结束才能进来。
public class Piao implements Runnable {
// 声明一个变量用来表示票库中票的数据
public int num = 10;
// 声明一个变量用来表示用户抢到了第几张票
public int count = 0;
public boolean flag =false;
@Override
public void run() {
while (!flag) {
sale();
}
}
public synchronized void sale() {
// 当票库里的票<0的时候,不再进行循环
if (num <= 0) {
flag = true;
return;
}
num--;
count++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了第" + count
+ "张票,还剩下" + num + "张票");
}
}
3、同步代码块
public class Piao implements Runnable {
// 声明一个变量用来表示票库中票的数据
public int num = 10;
// 声明一个变量用来表示用户抢到了第几张票
public int count = 0;
@Override
public void run() {
while (true) {
synchronized (this) {
// 当票库里的票<0的时候,不再进行循环
if (num <= 0) {
break;
}
num--;
count++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了第"
+ count + "张票,还剩下" + num + "张票");
}
}
}
}
4、测试类
public class Test {
public static void main(String[] args) {
Piao p = new Piao();
Thread t1 = new Thread(p, "张三");
Thread t2 = new Thread(p, "李四");
Thread t3 = new Thread(p, "如花");
t1.start();
t2.start();
t3.start();
}
}