# 多线程交替打印数字—多种实现

# 使用synchronized锁实现

public class Test {

    public static void main(String[] args) {
        mutilThreadPrintNum m1 = new mutilThreadPrintNum();
        Thread thread1 = new Thread(m1);
        Thread thread2 = new Thread(m1);
        thread1.setName("奇数");
        thread2.setName("偶数");
        thread1.start();
        thread2.start();
    }
}

class mutilThreadPrintNum implements Runnable {

    int num = 1;

    @Override
    public void run() {
        synchronized (this) {
            while (true) {
                // 唤醒wait()的一个或所有线程
                notify();
                if (num <= 100) {
                    System.out.println(Thread.currentThread().getName() + ":" + num);
                    num++;
                } else {
                    break;
                }
                try {
                    // wait会释放当前的锁,让另一个线程可以进入
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

# 打印结果
奇数:1
偶数:2
奇数:3
偶数:4
......
奇数:99
偶数:100

notify()wait()

# 使用valatile标志位实现

public class Test {

    static volatile boolean flag = true;
    static volatile int num = 1;

    public static void main(String[] args) {
        mutilThreadPrintNumOdd m1 = new mutilThreadPrintNumOdd();
        mutilThreadPrintNumEven m2 = new mutilThreadPrintNumEven();
        Thread thread1 = new Thread(m1);
        Thread thread2 = new Thread(m2);
        thread1.setName("奇数");
        thread2.setName("偶数");
        thread1.start();
        thread2.start();
    }

    public static class mutilThreadPrintNumOdd implements Runnable {

        @Override
        public void run() {
            while (num <= 100) {
                if (flag) {
                    System.out.println(Thread.currentThread().getName() + ":" + num);
                    num++;
                    flag = false;
                }
            }
        }
    }

    public static class mutilThreadPrintNumEven implements Runnable {

        @Override
        public void run() {
            while (num <= 100) {
                if (!flag) {
                    System.out.println(Thread.currentThread().getName() + ":" + num);
                    num++;
                    flag = true;
                }
            }
        }
    }
}

volatileflag

# 使用AtomicInteger+LockSupport实现

public class Test {

    public static AtomicInteger num = new AtomicInteger(1);

    public static Thread thread1 = null, thread2 = null;

    public static void main(String[] args) {
        mutilThreadPrintNumOdd m1 = new mutilThreadPrintNumOdd();
        mutilThreadPrintNumEven m2 = new mutilThreadPrintNumEven();
        thread1 = new Thread(m1);
        thread2 = new Thread(m2);
        thread1.setName("奇数");
        thread2.setName("偶数");
        thread1.start();
        thread2.start();

    }

    public static class mutilThreadPrintNumOdd implements Runnable {

        @Override
        public void run() {
            while (true) {
                if (num.get() % 2 != 0 && num.get() <= 100) {
                    System.out.println(Thread.currentThread().getName() + ":" + num);
                    // 原子递增
                    num.incrementAndGet();
                    // 获取许可,阻塞其他线程
                    LockSupport.park();
                } else {
                    // 释放许可,并将许可传递到偶数线程
                    LockSupport.unpark(thread2);
                }
            }
        }
    }

    public static class mutilThreadPrintNumEven implements Runnable {

        @Override
        public void run() {
            while (true) {
                if (num.get() % 2 == 0 && num.get() <= 100) {
                    System.out.println(Thread.currentThread().getName() + ":" + num);
                    // 原子递增
                    num.incrementAndGet();
                    // 获取许可,阻塞其他线程
                    LockSupport.park();
                } else {
                    // 释放许可,并将许可传递到奇数线程
                    LockSupport.unpark(thread1);
                }
            }
        }
    }
}

AtomicIntegerLockSupport

# 踩坑日志

LockSupport.park()
@Override
public void run() {
    while (true) {
        // 获取许可,阻塞其他线程
        LockSupport.park();
        if (num.get() % 2 != 0 && num.get() <= 100) {
            System.out.println(Thread.currentThread().getName() + ":" + num);
            // 原子递增
            num.incrementAndGet();
        } else {
            // 释放许可,并将许可传递到偶数线程
            LockSupport.unpark(thread2);
        }
    }
}

if

偶数线程:

jpspid
jstack pidWAITINGifelse