场景题Java多线程交替输出

发布时间:2024年01月23日

synchronized

package com.xcrj.concurrent.lock.synd;

/**
 * 同步
 * synchronized (obj) obj.wait(); obj.notify();
 * t1先输出1, t2再输出2
 * t2等t1输出1之后再执行输出2
 * 结果:12
 */
public class Synchronized6 {
    private static final Object obj = new Object();
    private static boolean t1Runned = false;

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (obj) {
                System.out.println("t1 1");
                t1Runned = true;
                obj.notify();
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            synchronized (obj) {
                try {
                    while (!t1Runned) {
                        obj.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t2 2");
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}
package com.xcrj.concurrent.lock.synd;
/**
 * 交替输出
 * synchronized(this) this.wait(); this.notifyAll();
 * t1输出a,t2输出b,t3输出c,共输出5次
 * abc abc abc abc abc
 */
public class Synchronized7 {
    public static void main(String[] args) {
        WaitNotify waitNotify=new WaitNotify(1, 5);
        Thread t1=new Thread(()->{
            waitNotify.hello(1, 2, "a");
        });
        Thread t2=new Thread(()->{
            waitNotify.hello(2, 3, "b");
        });
        Thread t3=new Thread(()->{
            waitNotify.hello(3, 1, "c");
        });

        t1.start();
        t2.start();
        t3.start();
    }

}

class WaitNotify {
    //控制执行顺序
    int id;
    int loopNum;
    WaitNotify (int id,int loopNum){
        this.id=id;
        this.loopNum=loopNum;
    }

    public void hello(int curId,int nxtIdx,String msg){
        for (int i = 0; i < loopNum; i++) {
            synchronized(this){
                //非当前可执行id则等待
                while(this.id!=curId){
                    try{
                        this.wait();
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
                
                System.out.println(msg);
                this.id=nxtIdx;
                this.notifyAll();
            }
        }
    }

}

LockSupport

package com.xcrj.concurrent.lock.ls;

import java.util.concurrent.locks.LockSupport;

/**
 * 同步
 * LockSupport.park(); LockSupport.unpark(t2);
 * t1先输出1, t2再输出2
 * t2等t1输出1之后再执行输出2
 */
public class LockSupport6 {
    public static void main(String[] args) {
        Thread t2=new Thread(()->{
            LockSupport.park();
            System.out.println("t2 2");
        },"t2");

        Thread t1=new Thread(()->{
            System.out.println("t1 1");
            LockSupport.unpark(t2);
        },"t1");

        t1.start();
        t2.start();
    }
}
package com.xcrj.concurrent.lock.ls;

import java.util.concurrent.locks.LockSupport;

/**
 * 交替输出
 * LockSupport.park(); LockSupport.unpark(nxtThd);
 * t1输出a,t2输出b,t3输出c,共输出5次
 * abc abc abc abc abc
 */
public class LockSupport7 {
    private static Thread t1;
    private static Thread t2;
    private static Thread t3;
    public static void main(String[] args) {
        ParkUnpark parkUnpark=new ParkUnpark(5);

        t1=new Thread(()->{
            parkUnpark.hello(t2, "a");
        },"t1");
        t2=new Thread(()->{
            parkUnpark.hello(t3, "b");
        },"t2");
        t3=new Thread(()->{
            parkUnpark.hello(t1, "c");
        },"t3");
        t1.start();
        t2.start();
        t3.start();

        LockSupport.unpark(t1);
    }
}

class ParkUnpark {
    private int loopNum;
    ParkUnpark (int loopNum){
        this.loopNum=loopNum;
    }
    public void hello(Thread nxtThd,String msg){
        for (int i = 0; i < this.loopNum; i++) {
            LockSupport.park();
            System.out.println(msg);
            LockSupport.unpark(nxtThd);
        }
    }
}

ReentrantLock

package com.xcrj.concurrent.lock.rl;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 同步
 * lock.lock(); lock.unlock(); c.await(); c.signal(); 
 * t1先输出1, t2再输出2
 * t2等t1输出1之后再执行输出2
 */
public class Lock_ReentrantLock6 {
    private static final ReentrantLock lock=new ReentrantLock();
    private static final Condition c=lock.newCondition();
    private static boolean t1Runned=false;
    
    public static void main(String[] args) {
        //
        Thread t1=new Thread(()->{
            lock.lock();
            try{
                System.out.println("t1 1");
                t1Runned=true;
                c.signal();
            }finally{
                lock.unlock();
            }
        },"t1");

        //
        Thread t2=new Thread(()->{
            lock.lock();
            try{
                while(!t1Runned){
                    c.await();
                }
                System.out.println("t2 2");
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        },"t2");

        t1.start();
        t2.start();
    }
}
package com.xcrj.concurrent.lock.rl;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 交替输出
 * Condition c1 c2 c3; lock(); curc.await(); nxtc.signal(); unlock();
 * t1输出a,t2输出b,t3输出c,共输出5次
 * abc abc abc abc abc
 */
public class Lock_ReentrantLock7 {
    public static void main(String[] args) {
        AwaitSignal awaitSignal = new AwaitSignal(5);
        Condition c1 = awaitSignal.newCondition();
        Condition c2 = awaitSignal.newCondition();
        Condition c3 = awaitSignal.newCondition();

        Thread t1 = new Thread(() -> {
            awaitSignal.hello(c1, c2, "a");
        });
        Thread t2 = new Thread(() -> {
            awaitSignal.hello(c2, c3, "b");
        });
        Thread t3 = new Thread(() -> {
            awaitSignal.hello(c3, c1, "c");
        });

        t1.start();
        t2.start();
        t3.start();

        System.out.println("开始");
        awaitSignal.lock();
        try {
            // 唤醒t1线程
            // signal必须在lock和unlock之间
            c1.signal();
            System.out.println();
        } finally {
            awaitSignal.unlock();
        }
        // 主线程unlock()之后,c1, c2 ,c3才能执行
    }
}

class AwaitSignal extends ReentrantLock {
    private int loopNum;

    AwaitSignal(int loopNum) {
        this.loopNum = loopNum;
    }

    /**
     * 三个线程放到三个等待队列中
     * 
     * @param curc
     * @param nxtc
     * @param msg
     */
    public void hello(Condition curc, Condition nxtc, String msg) {
        for (int i = 0; i < this.loopNum; i++) {
            super.lock();
            try {
                // await 必须在lock和unlock之间
                curc.await();
                System.out.println(msg);
                nxtc.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                super.unlock();
            }
        }
    }
}
文章来源:https://blog.csdn.net/baidu_35805755/article/details/135786824
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。