Java多线程同步锁

同步监视器必须为唯一的对象

例如:this, *.class

若使用*.class时,报以下错误

则原因为: 线程操作的wait()notify()notifyAll()方法只能在同步控制方法或同步控制块内调用。如果在非同步控制方法或控制块里调用,程序能通过编译,但运行的时候,将得到 java.lang.IllegalMonitorStateException 异常,并伴随着一些含糊信息,比如 current thread is not owner(当前线程不是拥有者)。其实异常的含义是 调用wait()notify()notifyAll()的任务在调用这些方法前必须 ‘拥有’(获取)对象的锁。

解决方法: 在wait()notify()notifyAll()方法调用是加上调用的对象,例如:*.class.wait();

具体实现

使用两个线程间隔递增的打印0到100

  1. 使用*.class同步监视器
public class demo implements Runnable{

    public static int number = 0;

    @Override
    public void run() {
        while (true) {
            synchronized (demo.class) {
                demo.class.notify();
                if (number <= 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " : " + number++);
                    try {
                        demo.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else { System.exit(0); }

            }
        }
    }

    public static void main(String[] args) {
        demo demo = new demo();
        Thread thread1 = new Thread(demo);
        Thread thread2 = new Thread(demo);

        thread1.setName("线程1");
        thread2.setName("线程2");

        thread1.start();
        thread2.start();
    }
}
  1. 使用this同步监视器
public class demo implements Runnable{

    public static int number = 0;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                this.notify();
                if (number <= 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " : " + number++);
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else { System.exit(0); }

            }
        }
    }

    public static void main(String[] args) {
        demo demo = new demo();
        Thread thread1 = new Thread(demo);
        Thread thread2 = new Thread(demo);

        thread1.setName("线程1");
        thread2.setName("线程2");

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