线程(三)

原创
2016/10/13 18:31
阅读数 2

一、线程间的通信

1、wait,notify

两个要结合使用,必须放在synchronized代码块或方法中,采用对象锁进行wait,notify

public class WaitNotifyTest {

    private volatile List<String> list = new ArrayList<String>();

    public void add() {
        list.add("1");
    }

    public int size() {
        return list.size();
    }

    public static void main(String[] args) {
        final Object object = new Object();
        final WaitNotifyTest test = new WaitNotifyTest();

        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                synchronized (object) {
                    System.out.println(Thread.currentThread().getName());
                    for (int i=0; i<10; i++) {
                        test.add();
                        if (test.size() == 5) {
                            object.notify();
                            System.out.println("唤醒t2线程");
                        }
                    }
                }
            }
        }, "t1");

        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                synchronized (object) {
                    if (test.size() != 5) {
                        try {
                            System.out.println("---开始等待");
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("---" + Thread.currentThread().getName());
                }
            }
        }, "t2");

        thread2.start();
        thread1.start();
    }

我先启动thread2线程,他先拿到锁,然后到逻辑,发现条件不满足,调用锁wait()释放锁,开始等待,然后thread1拿到锁之后,开始添加元素,到条件满足,调用锁的notify()去唤醒thread2,但是thread1不会释放自己锁,两个线程还存在竞争拿锁。

使用:wait,notify必须配合synchronized关键字使用

wait()会释放锁,notify()不会释放锁

public class QuenueTest {

    // 往一个集合中添加元素,take get
    public static volatile List<String> quene = new ArrayList<String>();

    public volatile int MAX_NUMBER = 5;

    public volatile int MIN_NUMBER = 0;

    public static AtomicInteger size = new AtomicInteger(5);

    Object lock = new Object();

    public void put(String string) {
        synchronized (lock) {
            while (size.get() == MAX_NUMBER) {
                try {
                    System.out.println("等待添加");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            quene.add(string);
            size.incrementAndGet();
            lock.notify();
            System.out.println("--添加");
        }
    }

    public String take() {
        synchronized (lock) {
            while (size.get() == MIN_NUMBER) {
                try {
                    System.out.println("等待取出");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            String string = quene.remove(0);
            size.decrementAndGet();
            lock.notify();
            System.out.println("--取出");
            return string;
        }
    }

    public static void main(String[] args) {
        quene.add("1");
        quene.add("2");
        quene.add("3");
        quene.add("4");
        quene.add("5");


        final QuenueTest test = new QuenueTest();
        Thread thread = new Thread(new Runnable() {
            public void run() {
                test.put("6");
                test.put("7");
            }
        });

        thread.start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                test.take();
                test.take();
            }
        });

        thread1.start();
    }

}

通过wait(),notify()模拟一个队列,设置最大、最小值,put,take的判断

2、ThreadLocal

 

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部