📜  Java中的线程间通信(1)

📅  最后修改于: 2023-12-03 14:42:58.986000             🧑  作者: Mango

Java中的线程间通信

在多线程应用程序中,线程之间的通信是非常重要的。Java提供了一些机制来实现线程间通信,包括共享变量、wait()、notify()、notifyAll()等。

共享变量

共享变量是指多个线程可以访问和修改的变量。当多个线程同时访问共享变量时,可能会出现竞争条件,导致数据不稳定。因此,必须采取措施来避免竞争状态。

在Java中,可以使用synchronized关键字来锁定共享变量,以确保在一个线程修改共享变量时,其他线程不能同时访问该变量。

下面是一个示例代码:

public class SharedVariableDemo {

    private int count;

    public synchronized void increment() {
        count++;
    }

    public synchronized void decrement() {
        count--;
    }

    public synchronized int getCount() {
        return count;
    }
}
wait()与notify()

wait()、notify()和notifyAll()是三个用于线程间通信的方法,它们可以用于任意对象,但必须在同步块中使用。

wait()

wait()的作用是将线程暂停,直到其他线程调用notify()或notifyAll()方法才会继续执行。在wait()之前,线程必须获得对象的锁,否则会抛出IllegalMonitorStateException异常。

wait()方法有以下两种形式:

public final void wait() throws InterruptedException

public final void wait(long timeout) throws InterruptedException

第一种形式将线程永远暂停,直到其他线程调用notify()或notifyAll()方法。

第二种形式将线程暂停一段时间后,如果在timeout时间内没有其他线程调用notify()或notifyAll()方法,则线程会自动唤醒。

下面是一个示例代码:

public class WaitNotifyDemo {

    public static void main(String[] args) {

        final Object lock = new Object();

        Thread t1 = new Thread(() -> {

            synchronized (lock) {

                System.out.println("Thread-1: wait");

                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("Thread-1: done");
            }
        });

        Thread t2 = new Thread(() -> {

            synchronized (lock) {

                System.out.println("Thread-2: notify");

                lock.notify();

                System.out.println("Thread-2: done");
            }
        });

        t1.start();
        t2.start();
    }
}
notify()

notify()的作用是唤醒一个正在等待对象锁的线程。如果有多个线程等待对象锁,则只会唤醒其中一个线程。如果没有线程正在等待对象锁,则该方法没有任何作用。

notify()方法必须在同步块中使用,否则会抛出IllegalMonitorStateException异常。

notifyAll()

notifyAll()的作用是唤醒所有正在等待对象锁的线程。如果没有线程正在等待对象锁,则该方法没有任何作用。

notifyAll()方法必须在同步块中使用,否则会抛出IllegalMonitorStateException异常。

下面是一个示例代码:

public class NotifyAllDemo {

    public static void main(String[] args) {

        final Object lock = new Object();

        Thread t1 = new Thread(() -> {

            synchronized (lock) {

                System.out.println("Thread-1: wait");

                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("Thread-1: done");
            }
        });

        Thread t2 = new Thread(() -> {

            synchronized (lock) {

                System.out.println("Thread-2: wait");

                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("Thread-2: done");
            }
        });

        Thread t3 = new Thread(() -> {

            synchronized (lock) {

                System.out.println("Thread-3: notifyAll");

                lock.notifyAll();

                System.out.println("Thread-3: done");
            }
        });

        t1.start();
        t2.start();

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

        t3.start();
    }
}
总结

Java提供了多种方法来实现线程间通信,包括共享变量、wait()、notify()和notifyAll()。在使用这些方法时,要注意线程安全和死锁问题,以确保程序正常运行。