java synoch 加锁_线程间通信 - HappyCowboy - 博客园

线程之间需要一些协调通信,来共同完成一件任务。Java多线程中,线程之间通信最常用的两个方法是wait()与notify()

使用wait()与notify()实现线程间的通信,需注意:

①wait()与notify()必须配合synochnized关键字使用

②wait()会释放锁,notify()不会释放锁

1.不使用notify()与wait()实现通信:

参照demo1

public class TestWaitNotify {

private volatile static List list = new ArrayList();

public void add(){

list.add("bjsxt");

}

public int size(){

return list.size();

}

public static void main(String[] args) {

final TestWaitNotify list1 = new TestWaitNotify();

Thread t1 = new Thread(new Runnable() {

public void run() {

try {

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

list1.add();

System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");

Thread.sleep(500);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}, "t1");

Thread t2 = new Thread(new Runnable() {

public void run() {

while(true){

if(list1.size() == 5){

System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + " list size = 5 线程停止..");

throw new RuntimeException();

}

}

}

}, "t2");

t1.start();

t2.start();

}

}

运行结果:

01e6eb133b0347fffa54d0337c814957.png

demo1总结:该方式确实实现了线程间的通信,但是用法比较传统,使用不够灵活;

2.使用wait()与notify()方法实现线程间通信

代码参照demo2:

public class TestWaitNotify2 {

private volatile static List list = new ArrayList();

public void add(){

list.add("bjsxt");

}

public int size(){

return list.size();

}

public static void main(String[] args) {

final TestWaitNotify2 list2 = new TestWaitNotify2();

// 1 实例化出来一个 lock

// 当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用

final Object lock = new Object();

Thread t1 = new Thread(new Runnable() {

public void run() {

try {

synchronized (lock) {

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

list2.add();

System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");

Thread.sleep(500);

if(list2.size() == 5){

System.out.println("已经发出通知..");

lock.notify();

}

}

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}, "t1");

Thread t2 = new Thread(new Runnable() {

public void run() {

synchronized (lock) {

if(list2.size() != 5){

try {

//System.out.println("t2进入...");

lock.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");

throw new RuntimeException();

}

}

}, "t2");

t2.start();

t1.start();

}

}

运行结果:

2e024c7ba0ad68abb29ef4f4dfe54b66.png

demo2总结:

通过wait()与notify()虽然实现了线程间通信,但是不能实现实时通信,因为wait()方法释放锁,可是notify()不释放锁,只有等t1线程执行完了,t2线程才能拿到锁执行;

3.通过countDownLatch实现线程间实时通信

demo3代码如下:

public class TestWaitNotify2 {

private volatile static List list = new ArrayList();

public void add(){

list.add("bjsxt");

}

public int size(){

return list.size();

}

public static void main(String[] args) {

final TestWaitNotify2 list2 = new TestWaitNotify2();

// 1 实例化出来一个 lock

// 当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用

//final Object lock = new Object();

final CountDownLatch countDownLatch = new CountDownLatch(1);

Thread t1 = new Thread(new Runnable() {

public void run() {

try {

//synchronized (lock) {

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

list2.add();

System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");

Thread.sleep(500);

if(list2.size() == 5){

System.out.println("已经发出通知..");

countDownLatch.countDown();

//lock.notify();

}

}

//}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}, "t1");

Thread t2 = new Thread(new Runnable() {

public void run() {

//synchronized (lock) {

if(list2.size() != 5){

try {

//System.out.println("t2进入...");

//lock.wait();

countDownLatch.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");

throw new RuntimeException();

}

//}

}, "t2");

t2.start();

t1.start();

}

}

运行结果:

f00e73481d4b452274b0417064fc35e0.png

demo3总结:通过countDownLatch的awit()与countDown()方法(类似wait与notify)实现了线程间的实时通信,使用起来更灵活;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值