线程和进程
创建
-
extends Thread
-
implement Runnable
就绪
.start()
运行
阻塞
-
sleep(n)--->就绪
-
yield()
-
join()
-
wait()
死亡
守护线程&用户线程
-
守护线程
最后一个用户线程结束,结束
.setDaemon(true)
-
用户线程
创建的普通线程
线程安全
三大特性
原子性
线程任务不可再分。
int i = 1; i++;
原子类 AtomicXXX
可见性
线程之间的操作是互相不可见的。
volatile
//线程A如果,flag为true,就运行打印语句 A: true
Thread t1 = new Thread(() -> {
while (true) {
if (flag) {
System.out.println("A:" + flag);
}
}
});
//100ms之后将flag变为true
Thread t2 = new Thread(() -> {
try {
Thread.sleep(100);
flag = true;
System.out.println("B:" + flag);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
t2.start();
有序性
程序运行顺序不能改变
线程安全性解决方案-锁
锁的使用过程
每一个对象只有一把锁,
每个线程抢锁,谁先抢到这个线程就是锁的持有者。
持有锁的线程访问有synchronized 标记的方法/代码块
离开synchronized ,线程释放锁。
模拟场景
火车票抢购
有100张车票
多个站点在卖票 A,B,C
100票共享给A,B,C
每卖出一张票,票--;
当票==0,卖票终止。
Ticket
public class Ticket {
private Integer num;
private String name;
public Ticket(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public void sold(String name) {
synchronized (num) {
System.out.println("站点" + name + "售出一张票,还剩: " + (--num));
}
}