多线程与高并发4 LockSupport、3道题

(1)LockSupport

这儿parkunpark其实实现了waitnotify的功能,不过还是有一些差别的。

  1. park不需要获取某个对象的锁
  2. 因为中断的时候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实现

猜你喜欢

转载自www.cnblogs.com/zdcsmart/p/12582818.html