码迷,mamicode.com
首页 > 编程语言 > 详细

Java线程的wait(), notify()和notifyAll()

时间:2019-05-18 09:47:55      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:current   dex   thread   red   and   new   clear   ace   net   

wait(), notify()和notifyAll()方法用于在线程间建立关联. 在对象上调用wait()将使线程进入WAITTING状态, 直到其他线程对同一个对象调用notify()或notifyAll(). 在任何线程上, 对一个对象调用wait(), notify()和notifyAll(), 都需要先获得这个对象的锁, 就是说, 这些方法必须在synchronized方法或代码块中调用.

notify()

调用notify()时, 在所有WAITING状态的线程中只会有一个线程被通知, 这个选择是随机的, 被通知的线程并不会立即得到对象的锁, 而是一直等到调用notify()的线程释放锁, 在这之前线程都是BLOCKED状态. 当获得锁后, 就会从BLOCKED状态变为RUNNING状态. 例子

class Shared {
    synchronized void waitMethod() {
        Thread t = Thread.currentThread();
        System.out.println(t.getName() + " is releasing the lock and going to wait");
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.getName() + " has been notified and acquired the lock back");
    }

    synchronized void notifyOneThread() {
        Thread t = Thread.currentThread();
        notify();
        System.out.println(t.getName() + " has notified one thread waiting for this object lock");
    }
}

public class MainClass {
    public static void main(String[] args) {
        final Shared s = new Shared();
        //Thread t1 will be waiting for lock of object ‘s‘
        Thread t1 = new Thread() {
            @Override
            public void run() {
                s.waitMethod();
            }
        };
        t1.start();

        //Thread t2 will be waiting for lock of object ‘s‘
        Thread t2 = new Thread() {
            @Override
            public void run() {
                s.waitMethod();
            }
        };
        t2.start();

        //Thread t3 will be waiting for lock of object ‘s‘
        Thread t3 = new Thread() {
            @Override
            public void run() {
                s.waitMethod();
            }
        };
        t3.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //Thread t4 will notify only one thread which is waiting for lock of object ‘s‘
        Thread t4 = new Thread() {
            @Override
            public void run() {
                s.notifyOneThread();
            }
        };
        t4.start();
    }
}

.

notifyAll()

当线程在对象上调用notifyAll()时, 所有WAITING状态的线程都会被通知, 所有的线程都会从WAITING状态变成BLOCKED状态, 然后争抢对象的锁. 得到对象锁的线程, 将变成RUNNING状态, 而其他线程则继续保持BLOCKED状态继续等待获取对象锁. 例子

class Shared {
    synchronized void waitMethod() {
        Thread t = Thread.currentThread();
        System.out.println(t.getName() + " is releasing the lock and going to wait");
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.getName() + " has been notified and acquired the lock back");
    }

    synchronized void notifyAllThread() {
        Thread t = Thread.currentThread();
        notifyAll();
        System.out.println(t.getName() + " has notified all threads waiting for this object lock");
    }
}

public class MainClass {
    public static void main(String[] args) {
        final Shared s = new Shared();
        //Thread t1 will be waiting for lock of object ‘s‘
        Thread t1 = new Thread() {
            @Override
            public void run() {
                s.waitMethod();
            }
        };
        t1.start();

        //Thread t2 will be waiting for lock of object ‘s‘
        Thread t2 = new Thread() {
            @Override
            public void run() {
                s.waitMethod();
            }
        };
        t2.start();

        //Thread t3 will be waiting for lock of object ‘s‘
        Thread t3 = new Thread() {
            @Override
            public void run() {
                s.waitMethod();
            }
        };
        t3.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //Thread t4 will notify all threads which are waiting for lock of object ‘s‘
        Thread t4 = new Thread() {
            @Override
            public void run() {
                s.notifyAllThread();
            }
        };
        t4.start();
    }
}

.

一个生产者和消费者的例子

注意, 在1个生产1个消费的情况下, 是能确保生产和消费的互相通知的, 但是在2个生产1个消费的情况下, 有可能要多次notify后消费线程才能拿到queue的锁.

public class DemoThreadWait1 {
    Queue<Integer> queue = new LinkedList<>();

    public void consume() {
        synchronized (queue) {
            while (queue.isEmpty()) {
                try {
                    System.out.println("consume wait");
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("remove all");
                queue.clear();
                queue.notify();
            }
        }
    }

    public void produce(int i) {
        synchronized (queue) {
            if (queue.size() < 5) {
                System.out.println("add " + i);
                queue.add(i);
            }
            if (queue.size() >= 5) {
                queue.notify();
                try {
                    System.out.println("produce wait");
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        DemoThreadWait1 demo = new DemoThreadWait1();
        new Thread(()->{
            while(true) {
                demo.consume();
            }
        }).start();

        new Thread(()->{
            while(true) {
                demo.produce((int) (Math.random() * 1000));
            }
        }).start();

        new Thread(()->{
            while(true) {
                demo.produce((int) (Math.random() * 1000));
            }
        }).start();
    }
}

  

Java线程的wait(), notify()和notifyAll()

标签:current   dex   thread   red   and   new   clear   ace   net   

原文地址:https://www.cnblogs.com/milton/p/10884427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!