两个线程交替打印大小写字母

175 阅读1分钟

使用java的两个线程交替打印大小写字母,一个线程打印大写字母,一个线程打印小写字母。

1. 只使用synchronized

/**
 * @author Floweryu
 * @date 2021/6/8 15:46
 */
public class PrintAa {

    private static final Object lock = new Object();
    private static volatile boolean flag = true;

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 26;) {
                synchronized (lock) {
                    if (flag) {
                        System.out.print((char) ('A' + i));
                        flag = false;
                        ++i;	// 不能放在for的括号中
                    }
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 26;) {
                synchronized (lock) {
                    if (! flag) {
                        System.out.print((char)('a' + i));
                        flag = true;
                        ++i;	// 不能放在for的括号中
                    }
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}
// 输出:
// AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz

2. 使用volatile的可见性(这里不对flag添加volatile也可以)

/**
 * @author Floweryu
 * @date 2021/6/8 10:16
 */

public class Print {
    private static volatile boolean flag = false; // 这里不添加volatile也可以
    public static void main(String[] args) throws InterruptedException {

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 26;) {
                if (flag) {
                    System.out.print((char) ('a' + i));
                    flag = false;
                    i++;  // 这里i要写在外面,不知道为什么
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 26;) {
                if (!flag) {
                    System.out.print((char)('A' + i));
                    flag = true;
                    i++;    // 这里i要写在外面,不知道为什么
                }

            }
        });

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

// 输出:
// AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz

3. 使用synchronizedwait/notify

/**
 * @author Floweryu
 * @date 2021/6/8 15:46
 */
public class PrintAa {

    private static final Object lock = new Object();
//    private static volatile boolean flag = true;  这里使用notify所以不需要用flag
    private static int i = 0;
    private static int j = 0;

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (i < 26) {
                synchronized (lock) {
                    System.out.print((char) ('A' + i));
                    i++;
                    lock.notify();
                    if(i < 26) {
                        try {
                            lock.wait();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            while (j < 26) {
                synchronized (lock) {
                    System.out.print((char) ('a' + j));
                    j++;
                    lock.notify();
                    if(j < 26) {
                        try {
                            lock.wait();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}
// 输出
// AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz