JAVA两个线程交替打印

题目

两个线程,一个负责打印1,3,5.。。。99;
另一个负责打印2,4,6,。。。100;
要交替进行,最后打印出来的次序是1,2,3,4,5,6,。。。99,100

使用java.util.concurrent.locks.ReentrantLock;

分析,这里涉及 两个线程的同步,需要用到signal/await;
可以利用并发工具类ReentrantLock,结合这个锁所产生的Condition对象,每个线程各有一个Condition;

注意点:

(1)先打印奇数;
(2)通过await放弃锁之前,要用另一个线程的Condition对象的signal执行唤醒,以让另一个线程可以获取锁,继续执行逻辑; (这2个线程的执行逻辑都在Lock包裹住的逻辑中的,C/C++程序员会不习惯)

流程图

流程图,拿奇数打印线程为例:

Created with Raphaël 2.2.0 开始 进入可重入锁 赋初始值1 当前值<100? 当前标志打印奇数? 打印当前值,置当前打印奇数标记为false,当前值+2 唤醒偶数线程 结束 yes no yes

代码

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

/**

  • Created by Jungle on 2019/1/21.

*/

@Controller

public class lockcontroller {

//java线程并发库中的锁相当与(synchronized)
// 主/子线程的核心逻辑都要被此锁包裹住
Lock lock = new ReentrantLock();
//线程并发库中用于线程之间通讯的类相当于wait(),notify()
Condition condOdd = lock.newCondition();
Condition condEven = lock.newCondition();
volatile boolean  bPrintOdd = true; //优先打印奇数


@RequestMapping("/lockTest")
public String lockTest(Model model) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            threadPrintEven();
        }
    }).start();

    //let sub-thread started first (这个延迟,无所谓,只是表明奇数线程先执行还是后执行都可以保证结果符合预期)
    try {
                   Thread.sleep(5000);
    } catch (Exception e) {
                 e.printStackTrace();
     }

    threadPrintOdd();

 return "index";

}

void threadPrintEven()
{
lock.lock();
System.out.println(“even enter lock”);

   try {

       for (int i = 2; i <= 100; i += 2) {
           if (bPrintOdd) {
               condOdd.signal();
               System.out.println("even signal then wait");
               condEven.await();
           }

           System.out.println(i);
           bPrintOdd = true;
       }
   }catch (Exception e) {
       e.printStackTrace();
   }finally{
       lock.unlock();
   }

   System.out.println("even finished");

}

void threadPrintOdd()
{
lock.lock();
System.out.println("odd enter lock ");

   try {
       for (int i = 1; i < 100; i += 2) {
           if (!bPrintOdd) {
               condEven.signal();
               System.out.println("odd signal then wait");
               condOdd.await();
           }

           System.out.println(i);
           bPrintOdd = false;
       }
       //唤醒另一个线程,打印最后一个偶数
       if (!bPrintOdd) {
           condEven.signal();
       }
   }catch (Exception e) {
       e.printStackTrace();
   }finally {
       lock.unlock();
   }

   System.out.println("odd finished");

}
}

  • 关于 :java中的sleep()和wait()的区别 ,参考 [这儿]

https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值