JavaEE初阶——多线程

一:多线程打印问题

1.题目

有三个线程,线程名称分别为:a,b,c。每个线程打印自己的名称。
需要让他们同时启动,并按 c,b,a的顺序打印。

2.题解

2.1 思路分析

创建三个线程,分别命名为a,b,c。在b线程打印“b”之前,让它等待c线程结束;在a线程打印“a”之前,让它等待b线程结束。

2.2 代码实现

package Threading;

public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        // 创建三个线程
        Thread tc = new Thread(() -> {
            // 打印c
            System.out.print(Thread.currentThread().getName() + " ");
        }, "c");

        Thread tb = new Thread(() -> {
            try {
                // 等待c 执行完成
                tc.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 打印b
            System.out.print(Thread.currentThread().getName() + " ");
        }, "b");

        Thread ta = new Thread(() -> {
            try {
                // 等待b 执行完成
                tb.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 打印a
            System.out.print(Thread.currentThread().getName() + " ");
        }, "a");

        // 需要让他们同时启动,并按 c,b,a的顺序打印
        ta.start();
        tb.start();
        tc.start();
    }
}

在这里插入图片描述

二:多线程打印问题进阶版

1.题目

有三个线程,分别只能打印A,B和C。要求按顺序打印ABC,打印10次。

2.题解

2.1 思路分析

思路一:使用COUNT变量进行总控。

思路二:使用三个锁,分别控制。

2.2 代码实现

思路一代码实现:

package Threading;

public class Test9 {
    private static volatile int COUNTER = 0;
    private static Object lock = new Object();

    public static void main(String[] args) {
        // 创建三个线程,并指定线程名,每个线程名分别用A,B,C表示
        Thread t1 = new Thread(() -> {
            // 循环10次
            for (int i = 0; i < 10; i++) {
                // 执行的代码加锁
                synchronized (lock) {
                    // 每次唤醒后都重新判断是否满足条件// 每条线程判断的条件不一样,注意线程t1,t2
                    while (COUNTER % 3 != 0) {
                        try {
                            // 不满足输出条件时,主动等待并释放锁
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 满足输出条件,打印线程名,每条线程打印的内容不同
                    System.out.print(Thread.currentThread().getName());
                    // 累加计数
                    COUNTER++;
                    // 唤醒其他线程
                    lock.notifyAll();
                }
            }
        }, "A");

    Thread t2 = new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            synchronized (lock) {
                while (COUNTER % 3 != 1) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print(Thread.currentThread().getName());
                COUNTER++;
                lock.notifyAll();
            }
        }
    }, "B");

    Thread t3 = new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            synchronized (lock) {
                while (COUNTER % 3 != 2) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 换行打印
                System.out.println(Thread.currentThread().getName());
                COUNTER++;
                lock.notifyAll();
            }
        }
    }, "C");

    // 启动线程
        t1.start();
        t2.start();
        t3.start();
}
}

思路二代码实现:

public class Test10 {
    private static Object locker1 = new Object();
    private static Object locker2 = new Object();
    private static Object locker3 = new Object();
 
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker1) {
                        locker1.wait();
                    }
                    System.out.print("A");
                    synchronized (locker2) {
                        locker2.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread t2 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker2) {
                        locker2.wait();
                    }
                    System.out.print("B");
                    synchronized (locker3) {
                        locker3.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread t3 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker3) {
                        locker3.wait();
                    }
                    System.out.println("C");
                    synchronized (locker1) {
                        locker1.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        t2.start();
        t3.start();
 
        Thread.sleep(1000);
 
        // 从线程 t1 启动
        synchronized (locker1) {
            locker1.notify();
        }
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值