(1)LockSupport
这儿park
和unpark
其实实现了wait
和notify
的功能,不过还是有一些差别的。
park
不需要获取某个对象的锁- 因为中断的时候
park
不会抛出InterruptedException
异常,所以需要在park
之后自行判断中断状态,然后做额外的处理
package dayo4; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; /** * @author: zdc * @date: 2020-03-27 */ public class _1LockSupport { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(()->{ for (int i = 0; i < 10; i++) { System.out.println(i); if(i==5) LockSupport.park(); } }); t.start(); TimeUnit.SECONDS.sleep(2); LockSupport.unpark(t); } }
(2)题目1
实现一个容器,提供两个方法,add,size 写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束
- 1
package dayo4; import java.util.ArrayList; import java.util.List; /** * @author: zdc * @date: 2020-03-27 */ public class MyContainer1<T> { private List<T> list = new ArrayList<>(); public void add(T t) { list.add(t); } public int size() { return list.size(); } public static void main(String[] args) { Object lock = new Object(); MyContainer1<String> container = new MyContainer1<>(); new Thread(() -> { synchronized (lock) { if (container.size() != 5) { try { lock.wait(); //1 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("元素已经加到5"); lock.notify(); } }, "t1").start(); new Thread(() -> { synchronized (lock) { for (int i = 0; i < 10; i++) { container.add("element" + i); if (container.size() == 5) { //注意线程2要wait 这样线程1才会活的执行权 否则只是线程2只是被notify 但并没有获得cpu执行权.wait会释放锁, // notify仅仅只是通知,不释放锁)notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了, // 但不是马上得到锁,因为锁还在别人手里,别人还没释放 lock.notify(); try { lock.wait();//线程1释放锁 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(i+1); } } }, "t2").start(); } }
- 2
CountDownLatch
public class MyContainer2<T> { private List<T> list = new ArrayList<>(); public void add(T t) { list.add(t); } public int size() { return list.size(); } public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(1); MyContainer1<String> container = new MyContainer1<>(); new Thread(() -> { if (container.size() != 5) { try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("元素已经加到5"); } , "t1").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { container.add("element" + i); if (container.size() == 5) { countDownLatch.countDown(); try { countDownLatch.await(); //这儿存疑 因为此时N=0了 为什么线程t2会停住一下下呢? } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(i + 1); } }, "t2").start(); } }
- 3
LockSupport
package dayo4; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.LockSupport; /** * @author: zdc * @date: 2020-03-27 */ public class MyContainer2<T> { private List<T> list = new ArrayList<>(); public void add(T t) { list.add(t); } public int size() { return list.size(); } static Thread t2 = null; // public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(1); MyContainer1<String> container = new MyContainer1<>(); Thread t1 = new Thread(() -> { if (container.size() != 5) { LockSupport.park(); } System.out.println("元素已经加到5"); LockSupport.unpark(t2); } , "t1"); t1.start(); t2 = new Thread(() -> { for (int i = 0; i < 10; i++) { container.add("element" + i); if (container.size() == 5) { LockSupport.unpark(t1); LockSupport.park(); } System.out.println(i + 1); } }, "t2"); t2.start(); } }
(3)题目2
两个线程,分别打印AB,其中线程A打印1,2,3,4,5 B线程打印A,B,C....使之出现A1B2..... 的效果。
- wait notify
public class Demo { public static void main(String[] args) { Character[] characters1 = {'1', '2', '3', '4', '5'}; Character[] characters2 = {'A', 'B', 'C', 'D', 'E'}; Object lock = new Object(); new Thread(() -> { for (int i = 0; i < characters1.length; i++) { synchronized (lock) { System.out.println(characters1[i]); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } lock.notify(); } } }, "t1").start(); new Thread(() -> { for (int i = 0; i < characters2.length; i++) { synchronized (lock){ System.out.println(characters2[i]); lock.notify(); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "t2").start(); } }
- 2 ReentrantLock
(4)题目3
写一个固定容量同步容器,拥有put和get方法,以及getCount方法,能够支持多个生产者和多个消费者线程拥塞调用。
1)使用synchronized锁的notify、notifyAll来实现
2)使用ReentrantLock锁的notify、notifyAll来实现
3)直接使用BlockingQueue实现