java线程等待_Java-线程等待、唤醒与中断

一、sleep() 与 wait()

两者都会让当前线程进入等待状态。唤醒后都需要等待 CPU 资源,不一定会立即执行。若在等待期间被调用此线程的的 interrupt() 方法,将会产生 InterruptedException 异常。

wait() 是 Object 类的方法,会释放对象锁,并让出 CPU 资源。只能在 synchronized 下使用,使用 notify() 或 notiftAll() 唤醒。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//线程工厂,这里主要用来设置线程名字

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();//创建线程池

ThreadPoolExecutor threadPool = new ThreadPoolExecutor(6, 6, 0L,

TimeUnit.MILLISECONDS,new LinkedBlockingQueue(1024),

namedThreadFactory,newThreadPoolExecutor.AbortPolicy());

Object object= newObject();

threadPool.execute(()->{try{synchronized(object) {

object.wait();

System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAA");

}

}catch(InterruptedException e) {

e.printStackTrace();

}

});

threadPool.execute(()->{synchronized(object) {

System.out.println("BBBBBBBBBBBBBBBBBBBBBBBBBBB");

object.notify();

}

});

View Code

sleep() 是 Thread 类的静态方法,只会让出 CPU 资源。可以使低优先级的线程得到执行的机会。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//线程工厂,这里主要用来设置线程名字

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();//创建线程池

ThreadPoolExecutor threadPool = new ThreadPoolExecutor(6, 6, 0L,

TimeUnit.MILLISECONDS,new LinkedBlockingQueue(1024),

namedThreadFactory,newThreadPoolExecutor.AbortPolicy());

threadPool.execute(()->{try{//阻塞 1 秒

Thread.sleep(1000);

System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAA");

}catch(InterruptedException e) {

e.printStackTrace();

}

});

threadPool.execute(()->{

System.out.println("BBBBBBBBBBBBBBBBBBBBBBBBBBBB");

});

View Code

两个示例都保证了 B 会在 A 之前被打印

二、notify() 与 notifyAll()

与 wait() 配合使用。两者都会唤醒其他线程,且会释放对象锁,不会阻塞当前线程。

其中 notify() 只唤醒等待线程当中的一个,notifyAll() 会唤醒所有等待线程。

notify() 是随机唤醒的,不同的 JDK 版本,在等待队列中唤醒的线程,其位置在等待队列中不同。

JDK1.8 中 notify() 唤醒的是等待队列中的头节点,即等待时间最长的那个线程。

唤醒的线程为同一个对象锁的线程。唤醒一个或所有,都只有一个线程会获取到锁对象。

三、yield() 与 join()

yield() 是 Thread 类的静态原生 (native) 方法,作用是让出 CPU 资源,不会阻塞当前线程,但可能让出 CPU 资源后,系统重新调度后又会选择给该线程 CPU 资源。使用场景比较少。

join() 是 Thread 类实例的方法,可以使得一个线程在另一个线程结束后再执行。当前运行的线程将进入到等待状态直到另一个线程执行完成。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Thread t1 = newThread(){

@Overridepublic voidrun() {try{

Thread.sleep(1000);

System.out.println("A");

}catch(InterruptedException e) {

e.printStackTrace();

}

}

};

Thread t2= newThread(){

@Overridepublic voidrun() {try{

t1.join();

System.out.println("B");

}catch(InterruptedException e) {

e.printStackTrace();

}

}

};

t2.start();

t1.start();

View Code

示例中保证了 A 在 B 之前被打印

四、interrupt()

中断等待状态的线程,并抛出异常。相关方法有三个。

interrupt() 是 Thread 类实例的方法,给线程中断状态设置为 false,等线程进入到等待状态时就会被中断,并抛出异常

isInterrupted() 是 Thread 类实例的方法,检测线程的中断状态

interrupted() 是 Thread 类的静态方法,实质调用的是 currentThread().isInterrupted(true),作用是检测线程的中断状态,然后将状态设置为 true

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Thread t1 = newThread() {

@Overridepublic voidrun() {try{

System.out.println(Thread.currentThread().getName()+ "启动后的中断状态:" +Thread.currentThread().isInterrupted());

Thread.currentThread().interrupt();

System.out.println(Thread.currentThread().getName()+ "interrupt()后的中断状态:" +Thread.currentThread().isInterrupted());

System.out.println(Thread.currentThread().getName()+ "isInterrupted()获取中断状态:" +Thread.interrupted());

System.out.println(Thread.currentThread().getName()+ "interrupted()后的中断状态:" +Thread.currentThread().isInterrupted());

Thread.currentThread().interrupt();

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

System.out.println(Thread.currentThread().getName()+ "异常时中断状态:" +Thread.interrupted());

}

}

};newThread() {

@Overridepublic voidrun() {

System.out.println(t1.getName()+ "未启动时的中断状态:" +t1.isInterrupted());

System.out.println("=======================================================");

t1.start();try{

t1.join();

System.out.println("=======================================================");

System.out.println(t1.getName()+ "执行完时的中断状态:" +t1.isInterrupted());

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}.start();

View Code

5c7684eba31b0247c72b30b460426f83.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值