java线程唤醒与等待_java 线程并发中的等待与唤醒

在实际开发中,Object 类的三个用来实现线程同步的方法常常被用到,尤其在解决生产者-消费者问题的时候:wait、notify、notifyAll

package com.techlog.test.service;

import org.springframework.stereotype.Service;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

/**

* just for test

* Created by techlog on 16/5/20.

*/

@Service

public class PrintSortedThreadName {

private static List threadIds;

private static int index;

private static boolean start;

public static void main(String[] argv) {

threadIds = new ArrayList();

final Object lock = new Object();

int concurrentcount = 10;

start = false;

index = 0;

for (int i = 0; i < concurrentcount; i++) {

new Thread(new Process(lock)).start();

}

synchronized (lock) {

Collections.sort(threadIds);

start = true;

lock.notifyAll();

}

}

private static class Process implements Runnable {

private final Object lock;

public Process(Object lock) {

this.lock = lock;

}

@Override

public void run() {

synchronized (lock) {

threadIds.add(Thread.currentThread().getId());

while (threadIds.get(index) != Thread.currentThread().getId() || !start) {

try {

lock.wait();

} catch (InterruptedException e) {

System.out.println("wait interrupted");

}

}

System.out.println(Thread.currentThread().getId() + " : " + Thread.currentThread().getName());

index++;

lock.notifyAll();

}

}

}

}

上面的代码实现了一个简单的线程同步功能:按照线程 ID 从小到大的顺序输出线程名称

我们通过 main 方法创建了 concurrentcount 指定个数的线程

每一个线程都向 threadIds 写入了自己的 ThreadId,然后,调用 Object 的 wait 方法陷入等待(因为类共享的 start 变量没有被开启)

main 方法在此后将 threadIds 进行了排序,并打开了 start 开关,此后,waiting 状态的所有线程相继被唤醒,打印出了:

11 : Thread-0

12 : Thread-1

13 : Thread-2

14 : Thread-3

15 : Thread-4

16 : Thread-5

17 : Thread-6

18 : Thread-7

19 : Thread-8

20 : Thread-9

锁 lock 实现了两个目的:对共享数据(index、threadIds)的保护和线程同步

上面的代码很直观地展示出了 Object 对象的 wait 和 notifyAll 两个方法的用法

wait 方法让线程释放锁并陷入 waiting 状态,直到被唤醒,如果在 wait 方法中传递了可选的 timeout 参数,则线程会在相应时间后自动被唤醒,而 notifyAll 则唤醒在相应锁上所有处于 waiting 状态的线程

Object 还实现了 notify 方法,每次调用只唤醒一个在相应锁上所有处于 waiting 状态的线程,通常我们使用 notifyAll,如果将上面代码中的 notifyAll 换成 notify,则所有并发线程会陷入死锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值