使用两个线程交替打印1-100个数

113 阅读1分钟

1.思路

  • 1)一个线程打印奇数,另一个线程打印偶数
  • 2)利用synchronized锁住对象,实现对变量的安全访问
  • 3)一个线程拿到锁后,符合条件则打印,并唤醒另外一个线程(notify),不符合条件则释放锁(wait)

2.代码实现

private volatile int num = 1;
private volatile Object lockObj = new Object();
/**
 * 【使用两个线程交替打印1-100个数】
 * 思路:
 * 1)一个线程打印奇数,另一个线程打印偶数
 * 2)利用synchronized锁住对象,实现对变量的安全访问
 * 3)一个线程拿到锁后,符合条件则打印,并唤醒另外一个线程(notify),不符合条件则释放锁(wait)
 *
 *      volatile关键字: 保证了共享变量的可见性
 */
@Test
public void test01() throws InterruptedException {
    //打印奇数线程
    Thread thread1 = new Thread(new Runnable() {
        public void run() {
            while (true) {
                synchronized (lockObj) {
                    if (num > 100) {
                        return;
                    }
                    if (num % 2 == 1) {
                        System.out.println(Thread.currentThread().getName() + ":" + num);
                        num++;
                        lockObj.notify();
                    } else {
                        try {
                            lockObj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    });
    //打印偶数
    Thread thread2 = new Thread(new Runnable() {
        public void run() {
            while (true) {
                synchronized (lockObj) {
                    if (num > 100) {
                        return;
                    }
                    if (num % 2 == 0) {
                        System.out.println(Thread.currentThread().getName() + ":" + num);
                        num++;
                        lockObj.notify();
                    } else {
                        try {
                            lockObj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    });
    thread1.setName("线程1");
    thread2.setName("线程2");
    thread1.start();
    thread2.start();
    //防止主线程结束,子线程打印不出来的问题
    thread1.join();
    thread2.join();
}