关于Java线程通讯的学习日志

Java中线程通讯

主要涉及对并发线程的操控

1.利用synchronized进行对象锁定实现对线程的控制 

2.使用lock condition进行线程控制

3.使用管道(Piped)Stream

为什么要用线程通讯,常见的就是需要访问同一个对象,根据对象的值进行相关的操作
举个例子 

小王是个程序员,今天收到客户A反馈的线上bug需要修改,产品经理B告诉小王页面也有点问题需要调整。

小王同时只能干一件事,要么改bug,要么调整页面。那么小王怎么安排呢。
小王考虑了一下想到自己的方案,先把bug修改完成,等待客户反馈,然后修改页面,改完以后交于产品确认。

等待客户反馈的时间小王可以先去修改页面,但是如果客户反馈有问题,小王需要继续修复bug 

  • synchronized 实现

可以定义线程了 
FixBugThread 

public class FixBugThread2 implements Runnable {
    private Object person;
    public FixBugThread2(Object person){
        this.person = person;
    }

    @Override
    public void run() {
        synchronized (person)
        {
            System.out.println("*********修复bug中********");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("*********bug修复完成********");
            person.notify();
        }
    }
}

MakePageThread  
 


public class MakePageThread2 implements Runnable {
    private Object person;

    public MakePageThread2(Object person) {
        this.person = person;
    }

    @Override
    public void run() {
        synchronized (person) {
            System.out.println("*********页面调整中********");
            for (int i = 0; i < 10; i++) {
                System.out.println("*********页面调整中" + i*10 + "% ********");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("*********页面调整完成********");
            person.notify();
        }
    }
}

 

定义完以后 我们跑一下 

    public static void main(String[] args) throws InterruptedException {
        System.out.println("开始运行");
        Object a = new Object();
        FixBugThread2 fbt = new FixBugThread2(a);
        MakePageThread2 mpt = new MakePageThread2(a);
        new Thread(fbt).start();
        new Thread(mpt).start();
        System.out.println("结束运行");
}

运行结果:

开始运行
*********修复bug中********
*********bug修复完成********
*********页面调整中********
*********页面调整中0% ********
*********页面调整中10% ********
*********页面调整中20% ********
*********页面调整中30% ********
*********页面调整中40% ********
*********页面调整中50% ********
*********页面调整中60% ********
*********页面调整中70% ********
*********页面调整中80% ********
*********页面调整中90% ********
*********页面调整完成********
结束运行

 

但是这是理想情况,小王一次性把bug解决掉了,实际情况是小王修改完bug以后,在调整页面的过程过客户又找来了,bug没有完全修复,小王需要再次修改bug。那怎么处理呢?我们需要终止makePage线程,然后小王再次修改bug 

所以对于调整页面的线程类方法我们要加上自己的控制 

public class MakePageThread2 implements Runnable {
    private Object person;
    private  Boolean isEnabled = true;
    private  Integer runTime = 10;
    private  Integer currentRunCount = 0;

    public MakePageThread2(Object person) {
        this.person = person;
    }

    @Override
    public void run() {
/*        while (true)
            System.out.println("**************MakePage");*/
        synchronized (person) {
            System.out.println("*********页面调整中********");
            while (true)
            {

                while (isEnabled)
                {
                    System.out.println("*********页面调整中" + currentRunCount*10 + "% ********");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    currentRunCount++;
                    if( currentRunCount >=runTime)
                    {

                        person.notify();
                        break;
                    }
                }
                if(!isEnabled)
                {
                    try {
                        person.wait(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if( currentRunCount >=runTime)
                {

                    person.notify();
                    break;
                }
            }

            System.out.println("*********页面调整完成********");
            person.notify();
        }
    }

    public void stop()
    {
        isEnabled = false;
        System.out.println("*********页面调整被打断********");
    }
    public void continueRun()
    {
        isEnabled = true;
    }
}

这块代码主要目的是就是一直运行知道完成页面调整,如果中间外部通知需要打断,就暂停运行。等待外部通知。

所以 对应main中的调用 我就改成了如下代码 

        System.out.println("开始运行");
        Object a = new Object();
        FixBugThread2 fbt = new FixBugThread2(a);
        MakePageThread2 mpt = new MakePageThread2(a);
        Thread fixBugT = new Thread(fbt);


        Thread makePageT = new Thread(mpt);
        fixBugT.start();//修复bug
        makePageT.start();//调整页面
        System.out.println("主线程开始休眠");
        Thread.sleep(1000);
        System.out.println("主线程结束休眠");
        mpt.stop();//bug没改好 停止调整页面
        new Thread(fbt).start();//重新修改bug
        mpt.continueRun();//改完bug以后继续调整页面
  • Lock 实现 

使用Condition往往比使用传统的通知等待机制(Object的wait()/notify())要更灵活、高效,例如,我们可以使用多个Condition实现通知部分线程

 

  • PipedInputStream类 与 PipedOutputStream类

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值