关于线程的解决思路,最好不要从时间角度,优先级角度考虑。一般不要使用sleep和join。
LockSupport.unpark(); LockSupport.park();
- public class A {
- static Thread t1 = null;
- static Thread t2 = null;
- public static void main(String[] args) {
- String[] a = {"1","2","3","4","5"};
- String[] b = {"a","b","c","d","e"};
- t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < a.length; i++) {
- System.out.println(a[i]);
- LockSupport.unpark(t2);
- LockSupport.park();
- }
- }
- });
- t2 = new Thread(()->{
- for (int i = 0; i < b.length; i++) {
- LockSupport.park();
- System.out.println(b[i]);
- LockSupport.unpark(t1);
- }
- });
- t1.start();
- t2.start();
- }
- }
针对线程通信这块,比起使用wait和notify更灵活,因为可以指定多个condition
lock.newCondition() condition.signal(); condition.await();
- public class C {
- static CountDownLatch latch = new CountDownLatch(1); //可以指定谁先执行时使用,具体看B类
- static ReentrantLock lock = new ReentrantLock();
- static Condition condition1 = lock.newCondition();
- static Condition condition2 = lock.newCondition();
- public static void main(String[] args) {
- String[] a = {"1","2","3","4","5"};
- String[] b = {"a","b","c","d","e"};
- C c = new C();
- new Thread(()->{
- c.t1(a);
- }).start();
- new Thread(()->{
- c.t2(b);
- }).start();
- }
- void t1(String[] a) {
- lock.lock();
- for (int i = 0; i < a.length; i++) {
- try {
- System.out.println(a[i]);
- condition1.signal();
- condition2.await();
- } catch (Exception e) {
- e.printStackTrace();
- }
- condition1.signal();
- }
- lock.unlock();
- }
- void t2(String[] b){
- lock.lock();
- for (int i = 0; i < b.length; i++) {
- try {
- System.out.println(b[i]);
- condition2.signal();
- condition1.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- condition2.signal();
- }
- lock.unlock();
- }
- }
在这里可以看知道两个线程确实交替执行了(暂时没有控制线程先后顺序),但是,如果我想控制让哪个线程先执行,需要怎么做?想一想,在使用wait和notify的案例中给出答案。
synchronized notify(); wait();
可以看一下如何控制哪个线程先输出
- public class B {
- static CountDownLatch latch = new CountDownLatch(1);
- public static void main(String[] args) {
- String[] a = {"1","2","3","4","5"};
- String[] b = {"a","b","c","d","e"};
- B b1 = new B();
-
- new Thread(()->{
- b1.t1(a);
- }).start();
- new Thread(()->{
- b1.t2(b);
- }).start();
- }
- void t1(String[] a) {
- try {
- latch.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- synchronized (this){
- for (int i = 0; i < a.length; i++) {
- try {
- System.out.println(a[i]);
- notify();
- wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- notify();
- }
- }
- void t2(String[] b){
- synchronized (this){
- for (int i = 0; i < b.length; i++) {
- try {
- System.out.println(b[i]);
- latch.countDown();
- notify();
- wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- notify();
- }
- }
- }
LinkedTransferQueue是一个由链表结构组成的无界阻塞TransferQueue队列。
LinkedTransferQueue是SynchronousQueue和LinkedBlockingQueue的合体,性能比LinkedBlockingQueue更高(没有锁操作),比SynchronousQueue能存储更多的元素。相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和transfer方法。
transfer:调用此方法后要等到有消费者获取此元素之后才返回,不然就一直阻塞。
take和poll: 如果为空就一直阻塞.
- public class D {
- public static void main(String[] args) {
- String[] a = {"1","2","3","4","5"};
- String[] b = {"a","b","c","d","e"};
- LinkedTransferQueue
queue = new LinkedTransferQueue<>(); - new Thread(()->{
- try {
- for (int i = 0; i < a.length; i++) {
- System.out.println(queue.take());
- queue.transfer(a[i]);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }).start();
- new Thread(()->{
- for (int i = 0; i < b.length; i++) {
- try {
- queue.transfer(b[i]);
- System.out.println(queue.take());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }