1、线程的生命周期
1.1、JDK 中用 Thread.State 枚举表示了线程的几种状态
1.2、线程状态转换图
1.3、查看线程状态
package state_;
public class ThreadState_ {
public static void main(String[] args) throws InterruptedException {
T t = new T();
System.out.println(t.getName() + "状态: " + t.getState());
t.start();
while (Thread.State.TERMINATED != t.getState()) {
System.out.println(t.getName() + "状态: " + t.getState());
Thread.sleep(500);
}
System.out.println(t.getName() + "状态: " + t.getState());
}
}
class T extends Thread {
@Override
public void run() {
while (true) {
for (int i = 0; i < 10; i++) {
System.out.println("hi " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
}
}
2、线程的同步
2.1、问题引出
2.2、Synchronized
2.2.1、线程同步机制
2.2.2、同步具体方法 - Synchronized
2.2.3、分析同步原理
3、互斥锁
3.1、基本介绍
3.2、使用互斥锁来解决售票问题
package syn;
public class SellTicket {
public static void main(String[] args) {
SellTicket03 sellTicket03 = new SellTicket03();
new Thread(sellTicket03).start();
new Thread(sellTicket03).start();
new Thread(sellTicket03).start();
}
}
class SellTicket03 implements Runnable {
private int ticketNum = 100;
private boolean loop = true;
Object object = new Object();
public synchronized static void m1() {
}
public static void m2() {
synchronized (SellTicket03.class) {
System.out.println("m2");
}
}
public void sell() {
synchronized (object) {
if (ticketNum <= 0) {
System.out.println("售票结束...");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票"
+ " 剩余票数=" + (--ticketNum));
}
}
@Override
public void run() {
while (loop) {
sell();
}
}
}
class SellTicket01 extends Thread {
private static int ticketNum = 100;
@Override
public void run() {
while (true) {
if (ticketNum <= 0) {
System.out.println("售票结束...");
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票" + " 剩余票数=" + (--ticketNum));
}
}
}
class SellTicket02 implements Runnable {
private int ticketNum = 100;
@Override
public void run() {
while (true) {
if (ticketNum <= 0) {
System.out.println("售票结束...");
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票" + " 剩余票数=" + (--ticketNum));
}
}
}
3.3、注意事项和细节
4、线程的死锁
4.1、基本介绍
多个线程都占用了对方的锁资源,但不肯相让,导致了死锁,在编程是一定要避免死锁的发生
4.2、形象的比喻
妈妈:你先完成作业,才让你玩手机 小明:你先让我玩手机,我才完成作业
4.3、代码实现
package syn;
public class DeadLock_ {
public static void main(String[] args) {
DeadLockDemo A = new DeadLockDemo(true);
A.setName("A 线程");
DeadLockDemo B = new DeadLockDemo(false);
B.setName("B 线程");
A.start();
B.start();
}
}
class DeadLockDemo extends Thread {
static Object o1 = new Object();
static Object o2 = new Object();
boolean flag;
public DeadLockDemo(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
if (flag) {
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + " 进入 1");
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + " 进入 2");
}
}
} else {
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + " 进入 3");
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + " 进入 4");
}
}
}
}
}
5、释放锁
5.1、下面操作会释放锁
5.2、下面操作不会释放锁
|