volatile实现
-
package com.jeff.base.conn008;
-
import java.util.ArrayList;
-
import java.util.List;
-
/**
-
* 定义t1和t2两个线程:
-
* t1线程往list中加入元素
-
* t2线程发现list元素个数为5时抛出异常,停止t2线程
-
*
-
* @author jeff
-
* @param args
-
*/
-
public class ListAdd1 {
-
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 ListAdd1 list1 = new ListAdd1();
-
Thread t1 = new Thread(new Runnable() {
-
@Override
-
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() {
-
@Override
-
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();
-
}
-
}
打印结果:
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程收到通知:t2 list size = 5 线程停止..
-
Exception in thread "t2" java.lang.RuntimeException
-
at com.jeff.base.conn008.ListAdd1$2.run(ListAdd1.java:50)
-
at java.lang.Thread.run(Thread.java:722)
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
wait和notify实现
-
package com.jeff.base.conn008;
-
import java.util.ArrayList;
-
import java.util.List;
-
import java.util.Queue;
-
import java.util.concurrent.CountDownLatch;
-
import java.util.concurrent.LinkedBlockingDeque;
-
import java.util.concurrent.LinkedBlockingQueue;
-
/**
-
* wait notfiy 方法,wait释放锁,notfiy不释放锁
-
* @author jeff
-
*
-
*/
-
public class ListAdd2 {
-
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 ListAdd2 list2 = new ListAdd2();
-
// 1 实例化出来一个 lock
-
// 当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用
-
final Object lock = new Object();
-
// final CountDownLatch countDownLatch = new CountDownLatch(1);
-
Thread t1 = new Thread(new Runnable() {
-
@Override
-
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() {
-
@Override
-
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();
-
}
-
}
打印结果:
-
t2进入...
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
已经发出通知..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t2收到通知线程停止..
-
Exception in thread "t2" java.lang.RuntimeException
-
at com.jeff.base.conn008.ListAdd2$2.run(ListAdd2.java:72)
-
at java.lang.Thread.run(Thread.java:722)
我们发现以后结果并不是实时的,分析下执行过程:
t2线程先执行,执行到await方法时释放锁,然后t1获得锁,当t1添加5个元素后,调用notify方法唤醒t2线程,但是notify方法并不释放锁,所以t2线程此时并不能得到锁,直到t1线程添加完10个元素以后释放锁,t2线程await才不再阻塞,打印“收到通知线程停止”。
CountDownLatch方式
-
package com.jeff.base.conn008;
-
import java.util.ArrayList;
-
import java.util.List;
-
import java.util.Queue;
-
import java.util.concurrent.CountDownLatch;
-
import java.util.concurrent.LinkedBlockingDeque;
-
import java.util.concurrent.LinkedBlockingQueue;
-
/**
-
* wait notfiy 方法,wait释放锁,notfiy不释放锁
-
* @author jeff
-
*
-
*/
-
public class ListAdd2 {
-
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 ListAdd2 list2 = new ListAdd2();
-
// 1 实例化出来一个 lock
-
// 当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用
-
// final Object lock = new Object();
-
final CountDownLatch countDownLatch = new CountDownLatch(1);
-
Thread t1 = new Thread(new Runnable() {
-
@Override
-
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() {
-
@Override
-
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();
-
}
-
}
打印结果:
-
t2进入...
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
已经发出通知..
-
Exception in thread "t2" java.lang.RuntimeException
-
at com.jeff.base.conn008.ListAdd2$2.run(ListAdd2.java:72)
-
at java.lang.Thread.run(Thread.java:722)
-
当前线程:t1添加了一个元素..
-
当前线程:t2收到通知线程停止..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
-
当前线程:t1添加了一个元素..
执行countDown方法后,计数器减去1,变为0,t2线程停止阻塞实时开始执行...