这儿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); } }
实现一个容器,提供两个方法,add,size 写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束
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(); } }
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(); } }
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(); } }
两个线程,分别打印AB,其中线程A打印1,2,3,4,5 B线程打印A,B,C....使之出现A1B2..... 的效果。
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(); } }
public class Demo {
public static void main(String[] args) {
Character[] characters1 = {‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘};
Character[] characters2 = {‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘};
ReentrantLock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
new Thread(() -> {
lock.lock();
for (int i = 0; i < characters1.length; i++) {
System.out.println(characters1[i]);
condition2.signal();
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
condition2.signal(); //循环题结束后t1,t2最后肯定有一个没醒过来的所以要唤醒
lock.unlock();
}, "t1").start();
new Thread(() -> {
lock.lock();
for (int i = 0; i < characters2.length; i++) {
System.out.println(characters2[i]);
condition1.signal();
try {
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
condition1.signal();
lock.unlock();
}, "t2").start();
}
}
写一个固定容量同步容器,拥有put和get方法,以及getCount方法,能够支持多个生产者和多个消费者线程拥塞调用。
1)使用synchronized锁的notify、notifyAll来实现
2)使用ReentrantLock锁的notify、notifyAll来实现
3)直接使用BlockingQueue实现
原文:https://www.cnblogs.com/zdcsmart/p/12582818.html