solitaryclown

线程按顺序交替执行

2021-12-21
solitaryclown

要求

创建3个线程,按照顺序分别打印”A”、”B”、”C”,循环n次

方法一:wait-notify

package com.huangbei.test1;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.LockSupport;

@Slf4j(topic = "c.Test-线程顺序执行")
public class Test2 {
    public static void main(String[] args) {

        //创建三个线程

        WaitNotify wn = new WaitNotify(1, 10);
        new Thread(() -> {
            wn.print("A", 1, 2);
        }).start();
        new Thread(() -> {
            wn.print("B", 2, 3);
        }).start();
        new Thread(() -> {
            wn.print("C", 3, 1);
        }).start();
    }
}

@Slf4j(topic = "c.WaitNotify")
class WaitNotify {
    //设置一个等待变量
    private int flag;
    //循环次数
    private int loopN;

    WaitNotify(int initialFlag, int loopN) {
        this.flag = initialFlag;
        this.loopN = loopN;
    }

    public void print(String content, int waitFlag, int nextFlag) {
        for (int i = 0; i < loopN; i++) {
            synchronized (this) {
                while (flag != waitFlag) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("{}", content);
                flag = nextFlag;
                //记得要唤醒等待的线程
                notifyAll();
            }
        }
    }
}

方法二:wait-signal

package com.huangbei.test1;

import com.huangbei.util.Sleeper;
import lombok.extern.slf4j.Slf4j;

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

@Slf4j(topic = "c.Test-线程顺序执行")
public class Test3 {
    public static void main(String[] args) {
        AwaitSignal as = new AwaitSignal(10);
        Condition c1 = as.newCondition();
        Condition c2 = as.newCondition();
        Condition c3 = as.newCondition();
        new Thread(() -> {
            as.print("A", c1, c2);
        }).start();
        new Thread(() -> {
            as.print("B", c2, c3);
        }).start();
        new Thread(() -> {
            as.print("C", c3, c1);
        }).start();

        //主线程1s后唤醒第一个线程
        Sleeper.sleep(1);
        try {
            as.lock();
            c1.signal();
        } finally {
            as.unlock();
        }

    }
}

@Slf4j(topic = "c.AwaitSignal")
class AwaitSignal extends ReentrantLock {
    private int loopN;

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

    public void print(String content, Condition current, Condition next) {
        for (int i = 0; i < loopN; i++) {
            try {
                this.lock();
                try {
                    current.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("{}", content);
                //叫醒下一个线程
                next.signal();
            } finally {
                this.unlock();
            }
        }
    }
}

方法三:park&unpark

package com.huangbei.test1;

import com.huangbei.util.Sleeper;
import com.sun.org.apache.bcel.internal.generic.LoadClass;
import lombok.extern.slf4j.Slf4j;

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

@Slf4j(topic = "c.Test-线程顺序执行")
public class Test4 {
    static  Thread t1,t2,t3;
    public static void main(String[] args) {
        ParkUnpark pu = new ParkUnpark(10);

        t1 = new Thread(() -> {
            pu.print("A", t2);
        });
        t2 = new Thread(() -> {
            pu.print("B", t3);
        });
        t3 = new Thread(() -> {
            pu.print("C", t1);

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

        Sleeper.sleep(1);
        LockSupport.unpark(t1);

    }
}

@Slf4j(topic = "c.park-unpark")
class ParkUnpark {
    private int loopN;

    ParkUnpark(int loopNumber) {
        this.loopN = loopNumber;
    }

    public void print(String content, Thread next) {
        for (int i = 0; i < loopN; i++) {
            LockSupport.park();
            log.debug("{}", content);
            LockSupport.unpark(next);
        }
    }
}


下一篇 Jmm

Comments

Content