欢迎访问宙启技术站
智能推送

如何使用Java实现多线程切换等待唤醒交替打印奇偶数

发布时间:2023-05-16 12:49:38

Java是一种高级的面向对象的编程语言,提供多线程的专业支持,可以在同一程序中同时执行多个线程。在多线程编程中,需要注意线程之间的同步和互斥,即一个线程在执行某些操作时,需要等待其他线程的某些操作完成后再进行下一步操作,这就需要使用到线程间的等待唤醒机制。

在本文中,我们将通过实现一个多线程切换等待唤醒的案例,来深入了解Java中的多线程和线程间的等待唤醒机制。

1. 实现思路

首先,我们需要明确本案例的需求:交替打印1~1000中的奇偶数,其中偶数由线程1打印,奇数由线程2打印。

为实现这一需求,我们需要使用到两个线程,同时需要定义一个共享变量作为打印的计数器,每次打印完成后需要把计数器加1,并在每次打印后等待对方线程的唤醒。在实现这一机制前,我们需要先了解几个重要的线程方法:wait、notify和notifyAll。

wait方法的作用是使当前线程进入等待状态,直到被唤醒或线程被中断才会退出。wait方法需要放在synchronized代码块中,表示线程在等待同步锁。当线程执行wait方法后,它会释放当前持有的同步锁,并且进入等待状态。wait方法有两种重载方法:带超时时间和不带超时时间。如果带有超时时间参数,就是在等待一定时间后自动唤醒线程。

notify方法的作用是唤醒一个在等待状态中的线程,如果有多个线程正在等待,则只唤醒其中的一个。notify方法也需要放在synchronized代码块中,表示唤醒的线程需要获取同步锁才能继续执行。

notifyAll方法的作用是唤醒所有等待状态中的线程,让它们都继续执行。notifyAll方法也需要放在synchronized代码块中,表示唤醒的线程需要获取同步锁才能继续执行。

了解了这几个线程方法后,我们就可以开始实现多线程切换等待唤醒交替打印奇偶数的案例了。

2. 实现代码

首先,我们来定义一个打印计数器count和两个线程OddThread和EvenThread。

public class WaitNotifyDemo {

    private static int count = 1;

    static class OddThread implements Runnable {

        @Override
        public void run() {

        }
    }

    static class EvenThread implements Runnable {

        @Override
        public void run() {

        }
    }
}

在OddThread中,我们需要使用while循环不停地判断并打印奇数,同时每次打印完成后需要把count加1,并唤醒EvenThread来打印偶数。在打印完成后,需要使用wait方法进入等待状态,并释放同步锁。代码如下:

@Override
        public void run() {
            while(count <= 1000) {
                synchronized (WaitNotifyDemo.class) {
                    if(count % 2 == 0) {
                        try {
                            // 继续等待偶数线程打印完毕
                            WaitNotifyDemo.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println(Thread.currentThread().getName() + ": " + count);
                        count++;
                        // 唤醒偶数线程打印
                        WaitNotifyDemo.class.notify();
                    }
                }
            }
        }

在EvenThread中也需要使用while循环不停地判断并打印偶数,同时每次打印完成后需要把count加1,并唤醒OddThread来打印奇数。在打印完成后,也需要使用wait方法进入等待状态,并释放同步锁。代码如下:

@Override
        public void run() {
            while(count <= 1000) {
                synchronized (WaitNotifyDemo.class) {
                    if(count % 2 == 1) {
                        try {
                            // 继续等待奇数线程打印完毕
                            WaitNotifyDemo.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println(Thread.currentThread().getName() + ": " + count);
                        count++;
                        // 唤醒奇数线程打印
                        WaitNotifyDemo.class.notify();
                    }
                }
            }
        }

最后,我们需要在主函数中启动两个线程并等待它们执行完毕。代码如下:

public static void main(String[] args) {
        Thread thread1 = new Thread(new OddThread(), "奇数线程");
        Thread thread2 = new Thread(new EvenThread(), "偶数线程");
        thread1.start();
        thread2.start();
        try {
            // 等待两个线程执行完成
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

3. 测试运行

运行以上代码,我们可以看到两个线程交替打印1~1000中的奇偶数,最终输出结果如下:

奇数线程: 1
偶数线程: 2
奇数线程: 3
偶数线程: 4
奇数线程: 5
偶数线程: 6
奇数线程: 7
偶数线程: 8
奇数线程: 9
偶数线程: 10
...
奇数线程: 999
偶数线程: 1000

可以看到,两个线程成功地交替打印了1~1000中的奇偶数,实现了我们的需求。

4. 总结

通过本案例的实现,我们深入了解了Java中多线程切换等待唤醒的机制,学习了wait、notify和notifyAll等重要的线程方法,并成功实现了多线程交替打印奇偶数的案例。在实际开发中,多线程编程非常常见,熟练掌握多线程编程技巧是非常重要的。