Java每日一练06多线程实现交叉打印输出6种方法后3种方法

本文介绍了使用Java的可重入锁+Condition以及synchronized关键字实现线程间的同步,确保特定顺序的代码执行。通过FooBar实例,展示了如何在两个线程间交替打印'foo'和'bar'。详细讲解了可重入锁的signal方法以及synchronized的wait和notifyAll方法的应用,同时给出了信号量Semaphore的实现方式。
摘要由CSDN通过智能技术生成

主方法

/**
 * 主方法
 * @author 驳壳毛瑟
 */
class FooBarTest {
    /*
     * 需求:
     *      两个不同的线程将会共用一个FooBar实例
     *      线程 A 将会调用 foo() 方法
     *      线程 B 将会调用 bar() 方法
     *      请设计修改程序,以确保"foobar"被输出n次
     */
    public static void main(String[] args) {
        FooBar fooBar = new FooBar(3); // foobar交替打印了3次

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    fooBar.foo(new Runnable() {
                        @Override
                        public void run() {
                            System.out.print("foo");
                        }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    fooBar.bar(new Runnable() {
                        @Override
                        public void run() {
                            System.out.print("bar\n");
                        }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

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

可重入锁 + Condition实现

/**
 * 可重入锁 + Condition
 *
 * @author 驳壳毛瑟
 * @apiNote
 * 实现过程类似生产者消费者模式
 * signal
 * signal调用的前提是已经获得了lock锁
 * 并且必须放在lock和unlock之间
 * 通俗理解就是使得线程重新进入运行状态
 * 和wait和notify方法类似
 * 没什么难的
 */
class FooBar4 {
    private int n;

    public FooBar4(int n) {
        this.n = n;
    }

    Lock lock = new ReentrantLock(true);
    private final Condition foo = lock.newCondition();
    volatile boolean flag = true;

    public void foo(Runnable printFoo) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            lock.lock();
            try {
                while (!flag) {
                    foo.await();
                }
                printFoo.run();
                flag = false;
                foo.signal();
            } finally {
                lock.unlock();
            }
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            lock.lock();
            try {
                while (flag) {
                    foo.await();
                }
                printBar.run();
                flag = true;
                foo.signal();
            } finally {
                lock.unlock();
            }
        }
    }
}

synchronized同步锁+唤醒实现

/**
 * synchronized同步锁+唤醒
 * @author 驳壳毛瑟
 * @apiNote 
 * 太简单,不想说
 */
class FooBar5 {
    private int n;
    // 标志位,控制执行顺序,true执行printFoo,false执行printBar
    private volatile boolean type = true;
    private final Object foo=  new Object(); // 锁标志

    public FooBar5(int n) {
        this.n = n;
    }
    public void foo(Runnable printFoo) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            synchronized (foo) {
                while(!type){
                    foo.wait();
                }
                printFoo.run();
                type = false;
                foo.notifyAll();
            }
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            synchronized (foo) {
                while(type){
                    foo.wait();
                }
                printBar.run();
                type = true;
                foo.notifyAll();
            }
        }
    }
}

/**
 * 信号量实现
 * @author 驳壳毛瑟
 * @apiNote 
 */
class FooBar6 {
    private int n;
    private Semaphore foo = new Semaphore(1);
    private Semaphore bar = new Semaphore(0);
    public FooBar6(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            foo.acquire();
            printFoo.run();
            bar.release();
        }
    }
    public void bar(Runnable printBar) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            bar.acquire();
            printBar.run();
            foo.release();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

muskfans

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值