java多线程实例之LeetCode交替打印Foobar,本地运行亲测

题目详细描述
解题思路主要在于信号量的使用!
话不多说,Foobar类,foo(),bar()方法,代码如下(注释超详细!)
本地IDEA执行(jdk1.8

import java.util.concurrent.Semaphore;

/**
 * 两个不同的线程将会共用一个FooBar实例
 * 其中一个线程调用foo()方法,另一个线程调用bar()方法
 * 确保"foobar"被输出n次
 */

public class FooBar {

    private int n;

    public FooBar(int n){
        this.n = n;
    }
    //public Semaphore(int permits){sync = new NonfairSync(permits);}
    // 新建信号量, permits值为 允许可用的初始许可数量,可以为负值,但是必须是有许可被赋予的情况下
    private  Semaphore sema_foo = new Semaphore(1); //sema_foo 初始许可为1
    private  Semaphore sema_bar = new Semaphore(0); //sema_bar 初始许可为0

    public void foo(){
        for(int i=1;i<=n;i++) {
            try {
                //请求获得许可,若存在许可,则获得的同时许可数量减一,若不存在则阻塞进入等待状态
                sema_foo.acquire(); //1.初始许可为1,可以获得许可,代码继续执行
                System.out.print("第"+i+"次交替:foo");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //释放许可,但必须在获得许可的前提下才能够释放,释放后许可数量加一
            sema_bar.release(); //2.初始许可为0,释放许可必须要先获得许可,线程阻塞,进入步骤3
            //2.1 因步骤3.1获得许可,此时可以释放,(第一次交替执行结束),从步骤1重新开始
        }
    }

    public void bar(){
        for(int i=1;i<=n;i++) {
            try {
                sema_bar.acquire(); //3.此时许可数为0,阻塞等待(异常),3.1获得释放的许可,代码继续执行
                System.out.println("bar");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sema_foo.release(); //4.释放许可,重新进入步骤3.1 4.1此时释放许可,线程阻塞,进入步骤2.1(参照步骤2)
        }
    }
    
    public static void main(String[] args) {

        FooBar fooBar = new FooBar(3);

        System.out.println("两个线程交替执行(输出如下):");

//        new Thread(new Runnable(){
//            @Override
//            public void run(){
//                fooBar.foo();
//            }
//        }).start();

//        new Thread(new Runnable(){
//            @Override
//            public void run(){
//                fooBar.bar();
//            }
//        }).start();

        //Anonymous new Runnable() can be replaced with lambda
        //Lambda syntax is not supported under Java 1.7 or earlier JVMs.
        new Thread(()->fooBar.foo()).start();
        new Thread(()->fooBar.bar()).start();
    }
}

输出如下:

两个线程交替执行(输出如下):
第1次交替:foobar
第2次交替:foobar
第3次交替:foobar
发布了22 篇原创文章 · 获赞 21 · 访问量 7012

猜你喜欢

转载自blog.csdn.net/weixin_43108122/article/details/100747335