美文网首页
线程交替打印奇偶数

线程交替打印奇偶数

作者: 0一缕星光0 | 来源:发表于2019-10-11 11:27 被阅读0次

    面试经常性问到要求手写线程交替打印奇偶数,其实就是考察对线程的灵活控制,本次就用2种方式交替打印奇偶数。并且比较下2中方式的效率


第一种:无限循环等待

0. 原理
    A线程由于竞争可能造成活锁情况,但是状态会被B线程的运行打破,当B线程执行i++操作后,i就会由奇数变成偶数,或者由偶数变成奇数,此时A线程的运行条件就满足了,运行得以持续。

1. 创建运行函数

const val final = 100000 // 截止的数字
var i = 0  // 自增的数字
val lock = Object() // 锁

fun main() {
    val start = System.currentTimeMillis()
    thread { printOdd(start) }
    thread { printEven(start) }
}

2. 两个线程交替打印数字

fun printOdd(start:Long) {
    while (i < final) {
        synchronized(lock) {if (i % 2 == 1) println("${Thread.currentThread().name}:${i++}")}
    }
    println("${Thread.currentThread().name} cost time:${System.currentTimeMillis() - start}")
}

fun printEven(start:Long) {
    while (i < final) {
        synchronized(lock) {if (i % 2 == 0) println("${Thread.currentThread().name}:${i++}")}
    }
    println("${Thread.currentThread().name} cost time:${System.currentTimeMillis() - start}")
}

3. 运行结果

此处省略一大堆···
Thread-0:99997
Thread-1:99998
Thread-0:99999
Thread-1:100000
Thread-0 cost time:2380
Thread-1 cost time:2380

第二种:使用Object的wait/notify机制

0. 原理
    使用kotlin的锁机制,在A线程执行完成后就再唤醒B线程执行,如此反复,避免了线程之间的竞争。

1. 创建运行函数

fun main() {
    val start = System.currentTimeMillis()
    thread { printOddSync(start) }
    thread { printEvenSync(start) }
}

2.两个线程交替打印数字

fun printOddSync(start:Long) {
    while (i < final) {
        synchronized(lock) {
            println("${Thread.currentThread().name}:${i++}")
            // 唤醒另外一个线程
            lock.notify()
            // 本线程进入等待
            lock.wait()
        }
    }
    // 退出线程前需要唤醒另外一个线程,避免另外一个线程无限等待
    // 因为不知道哪个线程先结束,所以2个线程都需要唤醒另外一个
    synchronized(lock) {
        lock.notify()
    }
    println("${Thread.currentThread().name} cost time:${System.currentTimeMillis() - start}")
}

fun printEvenSync(start:Long) {
    while (i < final) {
        synchronized(lock) {
            println("${Thread.currentThread().name}:${i++}")
            // 唤醒另外一个线程
            lock.notify()
            // 本线程进入等待
            lock.wait()
        }
    }
    // 退出线程前需要唤醒另外一个线程,避免另外一个线程无限等待
    // 因为不知道哪个线程先结束,所以2个线程都需要唤醒另外一个
    synchronized(lock) {
        lock.notify()
    }
    println("${Thread.currentThread().name} cost time:${System.currentTimeMillis() - start}")
}

3. 运行结果

此处省略一大堆···
Thread-1:99997
Thread-0:99998
Thread-1:99999
Thread-0:100000
Thread-0 cost time:1017
Thread-1 cost time:1017

综述

    使用wait\notify机制可以有效的避免由于线程竞争带来的性能损耗。


源码

线程交替打印奇偶数

相关文章

  • 线程交替打印奇偶数

        面试经常性问到要求手写线程交替打印奇偶数,其实就是考察对线程的灵活控制,本次就用2种方式交替打印奇偶数。并...

  • 一道线程面试题

    2个线程交替打印1-100内的数,线程A打印偶数,线程B打印奇数 打印结果如下: 实现代码

  • java两个线程交替打印奇偶数

    引言 java面试中经常会遇到这个问题,如何用两个线程交替打印奇偶数。线程A打印1,线程B打印2,线程A打印3,线...

  • LOCK--交替打印奇偶数

    两个线程交替打印奇偶数 public class TwoThreadLock { static Locklock ...

  • N个线程交替输出的问题

    1、两个不同的线程交替打印Kao、La。2、两个线程,一个打印100内的奇数一个打印100内的偶数,交替执行。 N...

  • 双线程交替打印奇偶数

    如何使用两个线程交替打印奇偶数? 这是一道经典的面试题,与生产消费者模型类似,都是在使用锁控制两个线程的线程安全问...

  • 交替打印奇偶数

    /** * 交替打印奇偶数 * 用condition来做信号量实现奇数偶数的交替打印 * @author wang...

  • 两个线程交替打印0-100的奇偶数

    题目:两个线程,其中一个线程打印奇数,另一个打印偶数,交替输出0-100 方法1:自旋判断 开启两个线程,每个线程...

  • 用程序实现两个线程交替打印 0~100 的奇偶数

    下班途中刷新闻时看到一道面试题:用程序实现两个线程交替打印 0~100 的奇偶数。看到“多线程交替”字样,瞬间就想...

  • 多线程同步交替打印奇偶数

    public class PrintSys{ /** * 定义线程 * @param str ...

网友评论

      本文标题:线程交替打印奇偶数

      本文链接:https://www.haomeiwen.com/subject/oxktmctx.html