• Java再学习——sleep(), wait(), notify(), notifyAll()


      首先一点就是Thread.sleep(long millis)方法是Thread类的静态方法,其他三个wait(), notify()和notifyAll()都是Object类的方法。

      sleep(long millis)方法的调用能使当前线程暂定执行指定时间(但是并没有释放任何锁),然后再继续运行。相当于设个闹钟然后睡觉,要么时间到被闹钟叫醒,要么就被interrupt()叫醒,然后继续干活。

      wait()方法则是让当前线程放弃调用wait()方法的对象的锁同时进入等待锁状态,然后只有通过该对象的notify()和notifyAll()方法才可以重新让线程进入抢夺状态。

      notify()方法则是唤醒某个等待中的线程(任意的,没有规律可寻)进入抢夺状态。

      notifyAll()方法则是唤醒所有等待中的线程进入抢夺状态。

    完整消费者例子如下:

    public class APP {
    
        public static void main(String[] args) throws Exception {
    
            class User {
                private int value;
    
                public User(int v) {
                    this.value = v;
                }
    
                public int getValue() {
                    return value;
                }
    
                public void setValue(int value) {
                    this.value = value;
                }
    
            }
    
            class Consumer extends Thread {
                private User user;
    
                public Consumer(User s) {
                    user = s;
                }
    
                @Override
                public void run() {
                    while (true) {
                        try {
                            synchronized (user) {
                                user.wait();
                                System.out.println("in " + getName()
                                        + " ,value -> " + user.getValue());
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            class Productor extends Thread {
                private User user;
                private int count = 0;
    
                public Productor(User s) {
                    user = s;
                }
    
                @Override
                public void run() {
                    while (true) {
                        try {
                            synchronized (user) {
                                int value = count++;
                                System.out.println("productor value is " + value);
                                user.setValue(value);
                                user.notify();
                            }
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            User user = new User(10);
    Consumer consumer1
    = new Consumer(user); consumer1.start(); Consumer consumer2 = new Consumer(user); consumer2.start(); Consumer consumer3 = new Consumer(user); consumer3.start(); Productor productor = new Productor(user); productor.start(); } }

    代码说明:

      1,要wait和notify的对象,最好是个Javabean,基本数据类型和被处理过的String等,都不适合做这种多线程处理,因为这些存在赋值操作的变量,会让线程莫名的失去本以为理所当然的Monitor,而实际上都已经丢失了,当然就会报错java.lang.IllegalMonitorStateException,而只有操作对象本身就保证了只有一个Monitor,关键是看谁拿了而已。

      2,基于第一点,所以在操作该对象时必须要进行同步,也就是要保证当前对其的操作时,你是独立占有它的。如例子中用的synchronized关键字对user进行代码块同步。

      3,同步的时候一定要记得限定同步的范围,比如例子中如果把synchronized代码块包括到while层,如果放在Consumer类还好写,但是如果放在Productor类,那个就没有任何意义了,因为这样会使得当前线程一直占有该对象,别的对象就只有一直等待了。所以一定要在处理完后记得放开它。

      4,notifyAll会唤醒所有的wait线程,但是并不一定就会 一起运行,还是要看线程个人造化。

  • 相关阅读:
    Java高级之类结构的认识
    14.8.9 Clustered and Secondary Indexes
    14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器
    14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构
    14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用
    14.8.1 Creating InnoDB Tables 创建InnoDB 表
    14.7.4 InnoDB File-Per-Table Tablespaces
    14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小
    14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小
    14.6.11 Configuring Optimizer Statistics for InnoDB 配置优化统计信息用于InnoDB
  • 原文地址:https://www.cnblogs.com/wytings/p/4960654.html
Copyright © 2020-2023  润新知