题目:自定义容器,提供新增元素(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(); } }