本文已参与「新人创作礼」活动,一起开启掘金创作之路。
线程插队
- join:线程的插队。插队的线程一旦插队成功,则肯定先执行完插入的线程的所有任务。
守护线程
- 用户线程:也叫工作线程,当线程任务执行完结束或用上述通知的方式结束线程。
- 守护线程:一般是为工作线程服务的,当所有用户的线程结束,守护线程自动结束
常见的守护线程:垃圾回收机制
//守护线程
public class Demo02RunnableDeamon {
public static void main(String[] args) throws InterruptedException {
T4 t4 = new T4();
// 将t4线程设为守护线程 (当主线程执行完时,子线程随之停止)
t4.setDaemon(true);
t4.start();
for (int i = 0; i < 10; i++) {
System.out.println("主线程任务执行。。。");
Thread.sleep(1000);
}
}
}
class T4 extends Thread {
@Override
public void run() {
int count = 0;
for (int i = 0; i < 20; i++) {
System.out.println("子线程" + count);
count++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程安全问题
当多线程访问了共享数据后,就会出现线程安全的问题。比如:多个窗口同时卖1-100号票。
线程安全问题是不能产生的,我们可以让一个线程在访问共享数据的时候,无论是否失去CPU的执行权,让其他的线程只能等待当前线程买完票,其他线程再进行卖票。
保证使用一个线程在卖票即可!
线程同步
多线程并发访问一个资源的安全性问题: 也就是解决重复票与不存在票问题,Java中提供了同步机制 ( synchronized ) 来解决。
完成同步的三种方式:
- 同步代码块
- 同步方法
- 锁机制
方式一:同步代码块
class TicketImpl implements Runnable {
private int ticket = 100;
// 1. 创建一个锁对象
Object lock = new Object();
@Override
public void run() {
while (true) {
// 2. 将涉及到共享资源的写操作(ticket)的代码放到同步代码块中
synchronized (lock) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "- 第" + ticket + "张");
try {
Thread.sleep(100);// 提高线程安全问题出现的频率,设置睡眠
} catch (InterruptedException e) {
e.printStackTrace();
}
ticket--;
}
}
}
}
}