线程有序输出的四(1)种写法

线程有序输出的四种写法

问题:三个线程有序输出abc
思路:各个线程有序的释放资源,得不到资源的线程陷入阻塞,最后使得线程之间有序协作啦!

法子一:只将输出方法 设为同步方法,别的,什么都不做,while循环,线程们去不停的抢吧,最笨的方法QAQ

输出方法:

 public synchronized void print(String name) {
        // System.out.println("线程  "+name+" 进来了");
        switch (name) {
            case "a":
                if (a > 0) {
                    a--;
                    System.out.println("A");
                    b++;
                    //一轮输出结束
                    end--;
                }
                break;
            case "b":
                if (b > 0) {
                    b--;
                    //     System.out.println("要输出b      的是  "+name);
                    System.out.println("B");
                    c++;
                }
                break;
            case "c":
                if (c > 0) {
                    c--;
                    //    System.out.println("要输出c      的是  "+name);
                    System.out.println("C");
                    a++;
                }
                break;
        }

        // System.out.println("线程  "+name+"  走了");
    }

内部线程类:

  class MyThread extends Thread {
        public MyThread(String tName) {
            super(tName);
        }

        @Override
        public void run() {
            while (end > 0) {
                print(getName());
            }
            long endtime = System.currentTimeMillis();
            System.out.println("线程   " + getName() + " 运行了  " + (endtime - start_time) + "ms");
        }
    }

测试类:

public class Ttest {
    int a = 1; //信号量a
    int b = 0; //信号量b
    int c = 0;  //信号量c
    int end = 100_000; //输出次数
    long start_time; //开始时间

    public Ttest() {

        start_time = System.currentTimeMillis();
        MyThread a = new MyThread("a");
        MyThread b = new MyThread("b");
        MyThread c = new MyThread("c");
        a.start();
        b.start();
        c.start();
    }

    public static void main(String[] args) {
        new Ttest();
    }

10万轮儿的运行时间:
在这里插入图片描述

方法二:采用wait()和notifyAll()方法 整体思想和法一大体样
输出方法:

public void print(String name) throws InterruptedException {
        // System.out.println(name+"  线程进入");
        synchronized (lock) {

            switch (name) {
                case "a":
                    while (a < 1) {
                        //当资源不足的时候 释放锁陷入阻塞
                        // System.out.println("线程  "+name+"资源不足陷入阻塞");
                        lock.wait();
                        //   System.out.println("线程  "+name+"被唤醒");
                    }
                    //资源足够 开始输出

                    //消耗资源
                    a--;
                    System.out.println("线程" + name + "输出  ==a");
                    //释放b资源
                    b++;

                    break;
                case "b":
                    while (b < 1) {
                        //当资源不足的时候 释放锁陷入阻塞
                        //    System.out.println("线程  "+name+"资源不足陷入阻塞");
                        lock.wait();
                        //  System.out.println("线程  "+name+"被唤醒");
                    }
                    //资源足够 开始输出

                    //消耗资源
                    b--;
                    System.out.println("线程" + name + "输出  ==b");
                    //释放c资源
                    c++;
                    break;
                case "c":
                    while (c < 1) {
                        //当资源不足的时候 释放锁陷入阻塞
                        //     System.out.println("线程  "+name+"资源不足陷入阻塞");
                        lock.wait();
                        //    System.out.println("线程  "+name+"被唤醒");
                    }
                    //资源足够 开始输出

                    //消耗资源
                    c--;
                    System.out.println("线程" + name + "输出  ==c");
                    //释放a资源
                    a++;

                    break;

            }
            //唤醒等待线程
            lock.notifyAll();
        }

    }

10万次的运行时间:

比方法一快了25%左右

方法三:使用Semaphore信号量
输出方法:

  public void print(String name) throws InterruptedException {
        
        switch (name){
            case "a":
                a.acquire();//请求操作
                System.out.println("线程:"+name+"输出  a");
                b.release();//释放资源操作
                break;
            case "b":
                b.acquire();
                System.out.println("线程:"+name+"输出  b");
                c.release();
                break;
            case "c":
                c.acquire();
                System.out.println("线程:"+name+"输出  c");
                a.release();
                break;

        }
    }
public class TTest3 {
    //abc信号量
    private Semaphore a, b, c;

    private long startTime;

    public TTest3(){
        startTime = System.currentTimeMillis();
        a = new Semaphore(1);
        b = new Semaphore(0);
        c = new Semaphore(0);
        Mt3 ta = new Mt3("a");
        Mt3 tb = new Mt3("b");
        Mt3 tc = new Mt3("c");
        tb.start();
        tc.start();
        ta.start();


    }


在这里插入图片描述
更快一些了噢

方法四: 自己封装 wait notify 成 pv操作 (操作系统噢)

public class ISemaphore {
    private int semaphore;//信号量

    public ISemaphore(int semaphore) {
        this.semaphore = semaphore;
    }

    public synchronized void p() throws InterruptedException {

        //若信号量小于等0 持有该对象的线程陷入阻塞
        while (semaphore <= 0) {
            this.wait();
        }
        //信号量减一
        semaphore--;
    }

    public synchronized void v() {
        //释放资源
        semaphore++;
        this.notifyAll();
    }
}

输出方法:

public void print(String name) throws InterruptedException {
        switch (name){
            case "a":
                //请求a资源
                a.p();
                System.out.println("线程"+name+"输出了 ==a");
                //释放b资源
                b.v();break;
            case "b":
                //请求b资源
                b.p();
                System.out.println("线程"+name+"输出了 ==b");
                //释放c资源
                c.v();break;
            case "c":
                //请求c资源
                c.p();
                System.out.println("线程"+name+"输出了 ==c");
                //释放a资源
                a.v();break;
        }
    }

测试类:

    private ISemaphore a, b, c;
    private long startTime;
    private int end = 100_000;

    public TestSemaphore(){
        a = new ISemaphore(1);
        b = new ISemaphore(0);
        c = new ISemaphore(0);
        startTime = System.currentTimeMillis();
        new myT("b",end).start();
        new myT("c",end).start();
        new myT("a",end).start();

    }

    public static void main(String[] args) {
        new TestSemaphore();
    }

10万次:
在这里插入图片描述
好像又快些了噢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值