最近准备面试,写了下几个简单小程序,无聊写到博客上。
代码如下:
public static void main(String[] args) {
List<String> list = new ArrayList<>(1);
Object lock = new Object();
Thread get = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (lock) {
while (list.size() == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
System.out.println(Thread.currentThread().getName() + " 消费,总量为++++" + list.size());
lock.notify();
}
}
}
}, "get");
Thread put = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (lock) {
while (list.size() != 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add("产品");
System.out.println(Thread.currentThread().getName() + " 生产,总量为--》" + list.size());
lock.notify();
}
}
}
}, "put");
get.start();
put.start();
}
就是一个简单的单生产和单消费的代码。
有几个点,提醒自己注意下:
1: SYNCHRONIZED
这个关键字的含义是: 当代码进入到它所限定的范围内时,不执行完毕,CPU是不会切换走的,除非自己主动放弃锁,,例如图上的 wait方法。
2:wait 和Notify 关键字
- wait方法是:等待,但是释放锁
- notify 方法: 就是唤醒等待的锁,但是此时唤醒 等待的锁后,等待的锁并不是立刻就获取了锁。
还是要唤醒锁的线程执行完它所在线程的synchronized的限定范围,这样被唤醒的才会尝试去唤醒锁。
3:唤醒之后
synchronized (lock) { 1
while (list.size() == 0) {
try {
lock.wait(); 2
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
System.out.println(Thread.currentThread().getName() + " 消费,总量为++++" + list.size());
lock.notify();
}
在图上的2处,释放锁完毕后,当被其他线程唤醒后,并且CPU切换到当前这个线程的时候,
不是再从1开始去尝试获取锁,而是直接在代码2处,尝试获取锁,如果还不成功,就再次进入阻塞状态
网友评论