题目:自定义容器,提供新增元素(add)和获取元素数量(size)方法。
启动两个线程。线程1向容器中新增10个数据。线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止。
===============================================================================================
使用三种方法:volatile, synchronized, CountDownLatch(门闩)
===============================================================================================
1.使用volatile修饰容器,只能保证容器数据的可见性保证不了完整性
public class TestBinFa2 {
public static void main(String[] args) {
final Test_01_Container t = new Test_01_Container();
new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < 50; i++){
System.out.println(" ");
System.out.println("前=======>"+t.container.toString());
t.add(new Integer(i));
System.out.println("后=======>"+t.container.toString());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("长度为=========>"+t.size());
if(t.size() == 45){
System.out.println("长度为=========>"+t.size()+"线程2中断了=======");
break;
}
}
}
}).start();
}
}
class Test_01_Container{
volatile List<Integer> container = new ArrayList<>();
public /*synchronized*/ void add(int num){
this.container.add(num);
}
public /*synchronized*/ int size(){
return this.container.size();
}
}
2.synchronized能保证数据的同步和并发,
public class TestBinFa3 {
public static void main(String[] args) {
final Test_01_Container1 t = new Test_01_Container1();
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
for(int i = 0; i < 10; i++){
System.out.println(" ");
System.out.println("前=======>"+t.container.toString());
t.add(new Integer(i));
System.out.println("后=======>"+t.container.toString());
if(t.size()==5){
lock.notifyAll();
try {
lock.wait();
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
synchronized (lock) {
while(true){
System.out.println("长度为=========>"+t.size());
if(t.size() != 5){
try {
lock.wait();当前线程进入等待
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("长度为=========>"+t.size()+"被中断");
lock.notifyAll();
break;
}
}
}
}).start();
}
}
class Test_01_Container1{
List<Integer> container = new ArrayList<>();
public void add(int num){
this.container.add(num);
}
public int size(){
return this.container.size();
}
}
3.使用门闩的方法,当add完后长度为5,就释放门闩,减掉门闩使其开放,
当检测长度不为5则等待门闩,
public class TestBinFa4 {
public static void main(String[] args) {
final Test_01_Container2 t = new Test_01_Container2();
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < 10; i++){
System.out.println(" ");
System.out.println("前=======>"+t.container.toString());
t.add(new Integer(i));
System.out.println("后=======>"+t.container.toString());
if(t.size()==5){
latch.countDown();释放门闩的
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
while(true){
System.out.println("长度为=========>"+t.size());
if(t.size() != 5){
try {
latch.await();等待门闩个数为0就能往下运行。
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("长度为=========>"+t.size()+"被中断");
break;
}
}
}).start();
}
}
class Test_01_Container2{
List<Integer> container = new ArrayList<>();
public void add(int num){
this.container.add(num);
}
public int size(){
return this.container.size();
}
}