Java多线程手写代码——奇偶交替输出,123123循环输出、A1B2C3交替输出

为什么wait()和notify()方法一定要搭配synchronized关键字才可以使用

因为如果不加synchronized关键字,会导致程序代码在多线程下,代码执行顺序混乱的问题。
如在A1B2C3交替输出的场景下: 如果不加synchronized关键字,两个线程同时执行,假如都执行到LOCK.wait()方法,就永远不会有人来唤醒它们了。

wait()方法

线程直接释放对象的锁,进入了等待队列,状态从RUNNING转变为WAITING,等待notify的唤醒.

notify()方法

唤醒在等待队列的线程,将在等待队列的线程移入同步队列,状态从WAITING等待变为BLOCKING阻塞,等到该线程的同步代码块执行完毕,会释放锁,然后同步队列的线程会争夺LOCK对象的monitor。

代码

奇偶交替输出

public class OddEvenPrinter extends Thread{
    private static Object LOCK = new Object();
    private static int end;
    private static volatile int num;
    OddEvenPrinter(int start,int end){
        this.num = start;
        this.end = end;
    }
    @Override
    public void run(){
        synchronized (LOCK){
            while(num <= end){
                LOCK.notify();
                System.out.println(Thread.currentThread().getName() + "的输出为:" + num);
                num++;
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            LOCK.notifyAll();
        }
    }
    public static void main(String[] args) {
        Thread threadA = new OddEvenPrinter(1,10);
        threadA.setName("OddThread");
        Thread threadB = new OddEvenPrinter(1,10);
        threadB.setName("EvenThread");
        threadA.start();
        threadB.start();
    }
}

123123循环输出

public class OneTwoThreePrinter implements Runnable{
    private static volatile int num;
    private static int times;
    private int targetNum;
    private static Object LOCK = new Object();

    public OneTwoThreePrinter(int num,int times,int targetNum){
        this.num = num;
        this.times = times;
        this.targetNum = targetNum;
    }

    @Override
    public void run() {

            synchronized (LOCK){
                for(int i = 0 ; i < times ; i++){
                    while(num % 3 != targetNum){
                        try {
                            LOCK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName() + "输出的num值为: "+(targetNum+1));
                    num++;
                    LOCK.notifyAll();
                }
            }

    }

    public static void main(String[] args) {
        OneTwoThreePrinter oneTwoThreePrinter0 = new OneTwoThreePrinter(0, 4,0);
        OneTwoThreePrinter oneTwoThreePrinter1 = new OneTwoThreePrinter(0, 4,1);
        OneTwoThreePrinter oneTwoThreePrinter2 = new OneTwoThreePrinter(0, 4,2);
        new Thread(oneTwoThreePrinter0,"Thread1").start();
        new Thread(oneTwoThreePrinter1,"Thread2").start();
        new Thread(oneTwoThreePrinter2,"Thread3").start();
    }

A1B2C3交替输出

public class LetterNumberPrinter implements Runnable{
    private static Object LOCK = new Object();

    @Override
    public void run() {
        
        synchronized (LOCK){
            for(int i = 0 ; i < 26 ; i++){
                if(Thread.currentThread().getName() == "NumberThread"){
            
                    LOCK.notify();
                    int num = i+1;
                    System.out.println(num);
                    try {
                        
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else if(Thread.currentThread().getName() == "LetterThread"){
                    LOCK.notify();
                    char c = (char) ((char) 'A'+i);
                    System.out.println(c);
                    try {
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            //防止还有子线程阻塞在代码块中
            LOCK.notifyAll();
        }
    }

    public static void main(String[] args) {
        LetterNumberPrinter thread1 = new LetterNumberPrinter();
        LetterNumberPrinter thread2 = new LetterNumberPrinter();
        new Thread(thread1,"LetterThread").start();
        new Thread(thread1,"NumberThread").start();

    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值