1、查看线程存活状态
Thread.isAlive()
Thread.getName()
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
printMsg();
}
}
public static void printMsg(){
Thread thread = Thread.currentThread();
//Thread.getName() 获取线程名称
System.out.println("name=["+thread.getName()+"]");
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.setName("MyThread"); //修改线程名称
System.out.println("before start(),the Thread Alive = " + myThread.isAlive());//判断线程存活状态
myThread.start();
System.out.println("just after start(),the Thread Alive = " + myThread.isAlive());
for (int i = 0; i < 10; i++) {
printMsg();
}
System.out.println("the end of Thread Alive = " + myThread.isAlive());
}
}
输出结果
before start(),the Thread Alive = false
just after start(),the Thread Alive = true
name=[main]
name=[main]
name=[main]
name=[main]
name=[MyThread]
name=[main]
name=[main]
name=[main]
name=[main]
name=[main]
name=[main]
name=[MyThread]
the end of Thread Alive = true
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
2、多线程同步锁
有三种同步锁:synchronize锁,lock锁,volatile锁
- synchronize锁是一般情况下Java多线程开发所使用的最常用同步锁。
- lock锁同样是常见同步锁。
- volatile锁是一种轻量同步锁,能够减轻同步锁所带来的的资源消耗,但只能所用在变量上。
lock锁与synchronize锁的区别:
- 两者都是可重入锁,自己可以再次获取自己的内部锁。
- synchronized是依赖于虚拟机的,而Lock锁依赖JDK。
- synchronized锁可以自动释放锁,而Lock锁必须要手动释放锁。
- synchronized锁的两个线程1和线程2,如果当前线程1获得锁,线程2等待,如果线程1阻塞,线程2会一致等待下去,而Lock锁不一定会等下去,如果尝试获几次取不到锁,线程2可以不用一直等待就结束了。
synchronize锁的使用场景:卖票
class MyThread extends Thread{
public static void main(String[] args) {
Ticket ticket=new Ticket();
Thread thread = new Thread(ticket,"售票员小张");
thread.start();
Thread thread1 = new Thread(ticket,"售票员小刘");
thread1.start();
}
}
//票务系统
class Ticket implements Runnable {
//总票数
private int ticketCount = 40;
@Override
public void run() {
while (true) {
//对票务类进行同步锁,避免线程产生脏数据
synchronized (Ticket.class) {
if (ticketCount > 0) {
try {
//小张在出票的时候被领导叫走了
//这个时候呢,小刘也要卖这张票
//线程睡眠是在模拟网络延迟的情况
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在售票,剩余" + (--ticketCount));
}
}
}
}
}
输出结果
售票员小张正在售票,剩余39
售票员小张正在售票,剩余38
售票员小张正在售票,剩余37
售票员小张正在售票,剩余36
售票员小刘正在售票,剩余35
售票员小刘正在售票,剩余34
售票员小刘正在售票,剩余33
售票员小刘正在售票,剩余32
售票员小刘正在售票,剩余31
售票员小刘正在售票,剩余30
售票员小刘正在售票,剩余29
售票员小刘正在售票,剩余28
售票员小刘正在售票,剩余27
售票员小刘正在售票,剩余26
售票员小刘正在售票,剩余25
售票员小刘正在售票,剩余24
售票员小刘正在售票,剩余23
售票员小刘正在售票,剩余22
售票员小刘正在售票,剩余21
售票员小刘正在售票,剩余20
售票员小张正在售票,剩余19
售票员小张正在售票,剩余18
售票员小刘正在售票,剩余17
售票员小刘正在售票,剩余16
售票员小刘正在售票,剩余15
售票员小刘正在售票,剩余14
售票员小刘正在售票,剩余13
售票员小刘正在售票,剩余12
售票员小刘正在售票,剩余11
售票员小刘正在售票,剩余10
售票员小刘正在售票,剩余9
售票员小刘正在售票,剩余8
售票员小刘正在售票,剩余7
售票员小刘正在售票,剩余6
售票员小刘正在售票,剩余5
售票员小刘正在售票,剩余4
售票员小刘正在售票,剩余3
售票员小刘正在售票,剩余2
售票员小张正在售票,剩余1
售票员小刘正在售票,剩余0
Lock锁使用场景:卖票
class MyThread extends Thread{
public static void main(String[] args) {
//创建锁对象
Lock lock=new ReentrantLock();
//创建要执行的任务
Ticket ticket=new Ticket(lock);
//创建线程并开启线程
Thread t1=new Thread(ticket,"售票员张小飞");
t1.start();
Thread t2=new Thread(ticket,"售票员关小羽");
t2.start();
}
}
class Ticket implements Runnable {
private Lock lock;
private int count = 40;
public Ticket(Lock lock) {
this.lock = lock;
}
@Override
public void run() {
while (true) {
//使用lock锁进行加锁
lock.lock();
if (count > 0) {
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "售出一张票,剩余" + (--count) + "张"