实现两个线程从0-100交替打印

  分享一道多线程面试题,只是拿来练手的,这里通过两种方式去实现0-100交替打印,大家无聊的话,可以瞅两眼。

一、Synchronized实现:

public class PrintNumberIncrInSynchronized {

    private static int number;
    private static final Object object = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            while (number < 100) {
                synchronized (object) {
                    //相对%2判断奇偶数,&效率更高
                    if ((number & 1) == 0) {
                        System.out.println(Thread.currentThread().getName() + ":" + number++);
                    }
                }
            }
        },"偶数").start();

        new Thread(() -> {
            while (number < 100) {
                synchronized (object) {
                    if ((number & 1) == 1) {
                        System.out.println(Thread.currentThread().getName() + ":" + number++);
                    }
                }
            }
        },"奇数").start();

    }

}

结果:
偶数:0
奇数:1
偶数:2
奇数:3
偶数:4
奇数:5
偶数:6
奇数:7
偶数:8
奇数:9
偶数:10
奇数:11
偶数:12
奇数:13
偶数:14
奇数:15
偶数:16
奇数:17
偶数:18
奇数:19
偶数:20
奇数:21
偶数:22
奇数:23
偶数:24
奇数:25
偶数:26
奇数:27
偶数:28
奇数:29
偶数:30
奇数:31
偶数:32
奇数:33
偶数:34
奇数:35
偶数:36
奇数:37
偶数:38
奇数:39
偶数:40
奇数:41
偶数:42
奇数:43
偶数:44
奇数:45
偶数:46
奇数:47
偶数:48
奇数:49
偶数:50
奇数:51
偶数:52
奇数:53
偶数:54
奇数:55
偶数:56
奇数:57
偶数:58
奇数:59
偶数:60
奇数:61
偶数:62
奇数:63
偶数:64
奇数:65
偶数:66
奇数:67
偶数:68
奇数:69
偶数:70
奇数:71
偶数:72
奇数:73
偶数:74
奇数:75
偶数:76
奇数:77
偶数:78
奇数:79
偶数:80
奇数:81
偶数:82
奇数:83
偶数:84
奇数:85
偶数:86
奇数:87
偶数:88
奇数:89
偶数:90
奇数:91
偶数:92
奇数:93
偶数:94
奇数:95
偶数:96
奇数:97
偶数:98
奇数:99
偶数:100

  启动两个线程,分别进行进行命名,并且只打印奇数和偶数。通过不断竞争monitor锁,只有满足if判断才会++和打印,最终能够实现要求。从实现过程能够看出来,需要不断竞争锁,而且很有可能不满足条件,不够高效。

二、wait和notify实现:

public class PrintNumberIncrInWaitAndNotify {

    private static int number;
    private static final Object object = new Object();

    public static void main(String[] args) throws InterruptedException{
        new Thread(new ToolClass(), "偶数").start();
        //这里休眠10ms保证偶数线程能够先执行
        Thread.sleep(10);
        new Thread(new ToolClass(), "奇数").start();
    }

    static class ToolClass implements Runnable {
        @Override
        public void run() {
            while (number <= 100) {
                synchronized (object) {
                    System.out.println(Thread.currentThread().getName() + ":" + number++);
                    object.notify();
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

结果:
偶数:0
奇数:1
偶数:2
奇数:3
偶数:4
奇数:5
偶数:6
奇数:7
偶数:8
奇数:9
偶数:10
奇数:11
偶数:12
奇数:13
偶数:14
奇数:15
偶数:16
奇数:17
偶数:18
奇数:19
偶数:20
奇数:21
偶数:22
奇数:23
偶数:24
奇数:25
偶数:26
奇数:27
偶数:28
奇数:29
偶数:30
奇数:31
偶数:32
奇数:33
偶数:34
奇数:35
偶数:36
奇数:37
偶数:38
奇数:39
偶数:40
奇数:41
偶数:42
奇数:43
偶数:44
奇数:45
偶数:46
奇数:47
偶数:48
奇数:49
偶数:50
奇数:51
偶数:52
奇数:53
偶数:54
奇数:55
偶数:56
奇数:57
偶数:58
奇数:59
偶数:60
奇数:61
偶数:62
奇数:63
偶数:64
奇数:65
偶数:66
奇数:67
偶数:68
奇数:69
偶数:70
奇数:71
偶数:72
奇数:73
偶数:74
奇数:75
偶数:76
奇数:77
偶数:78
奇数:79
偶数:80
奇数:81
偶数:82
奇数:83
偶数:84
奇数:85
偶数:86
奇数:87
偶数:88
奇数:89
偶数:90
奇数:91
偶数:92
奇数:93
偶数:94
奇数:95
偶数:96
奇数:97
偶数:98
奇数:99
偶数:100

  每次进行++操作并且打印之后,就会notify唤醒另一个因为wait()陷入Waiting状态的线程,然后调用wait(),释放monitor锁,另一个线程获取到锁,进行同样的操作,最终实现要求。

原文地址:https://www.cnblogs.com/huigelaile/p/11993189.html

时间: 2024-10-29 12:02:54

实现两个线程从0-100交替打印的相关文章

两个线程交替打印信息

看见一个关于两个线程交替打印信息的题目,题目大概是 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码. 写了两个版本,一个是用了mutex,不用条件变量:另外一个是用条件变量. 第一个,不用条件变量 1 #include <stdio.h> 2 #include <string.h> 3 #include <pthread.h> 4 5 6 7 const int LOOP_

设计四个线程,其中共两个线程每次对j增加1,另外两个线程每次对j减少1。循环100次,写出程序。

package cn.usst.DataTest6; /** * 设计四个线程,其中共两个线程每次对j增加1,另外两个线程每次对j减少1.循环100次,写出程序. * @ * */ public class DataTest6 { private int j; public static void main(String[] args) { DataTest6 dt = new DataTest6(); Inc inc = dt.new Inc(); Dec dec = dt.new Dec()

设计四个线程,当中共两个线程每次对j添加1,另外两个线程每次对j降低1。循环100次,写出程序。

package cn.usst.DataTest6; /** * 设计四个线程,当中共两个线程每次对j添加1,另外两个线程每次对j降低1.循环100次,写出程序. * @ * */ public class DataTest6 { private int j; public static void main(String[] args) { DataTest6 dt = new DataTest6(); Inc inc = dt.new Inc(); Dec dec = dt.new Dec()

经典面试题——两个线程交替打印奇数和偶数

前提 今天下班时候和同事聊天偶然听到面试题“两个线程交替打印奇数和偶数”的实现,这里做一个复盘. 复盘 场景一:线程A打印奇数,线程B打印偶数,线程A和线程B交替打印,使用对象监视器实现. 场景二:线程A打印奇数,线程B打印偶数,线程A和线程B交替打印,使用JDK提供的并发类库实现. 这两个场景中,场景一是一种比较古老的同步方式,本质由JVM实现:场景二是JDK1.5引入JUC包之后简化了并发编程的前提下的更简便的实现.下面针对两个场景做对应的实现. 场景一 场景一中,线程A和线程B交替打印奇数

两个线程交替打印1-99

参考https://github.com/crossoverJie/JCSprout/blob/master/src/main/java/com/crossoverjie/actual/TwoThread.java从线程方面实现交替打印. public class Test { volatile boolean isEven = false; @org.junit.Test public void testfda() throws InterruptedException { Thread a

经典笔试题:两个线程交替打印奇偶数

一.采用对象的wait() notify()方法实现 package com.gaopeng.programming; import java.util.concurrent.TimeUnit; /** * 经典笔试题:交替打印奇偶数 采用对象的wait() notify()方法实现 * * @author gaopeng * */ public class OddEvenThread { private static volatile Integer counter = 0; public s

Java多线程通信之两个线程分别打印AB各10次

一道经典的面试题目:两个线程,分别打印AB,其中线程A打印A,线程B打印B,各打印10次,使之出现ABABABABA.. 的效果 1 package com.shangshe.path; 2 3 public class ThreadAB { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 10 final Print business = new Print(); 11 12 new Threa

C#线程--5.0之前时代(二)、线程的同步

线程同步 说明:接上一篇,注意分享线程同步的必要性和线程同步的方法. 一.什么是线程同步: 在同一时间只允许一个线程访问资源的情况称为线程同步. 二.为什么需要线程同步: 避免竞争条件: 确保线程安全:(如果两个线程同时访问一个资源并对那个资源做修改,就不安全了) 现在的计算机变得越来越多核,每一个CPU可以独立工作,但是对于内存和外部资源.数据库的访问却可能因为不同线程的访问使数据产生异常,常见的例子就是银行的转账的例子不再赘述. 三.线程同步的方法: 同步代码中重要的部分: 使对象不可改变:

java多线程 更优雅的实现线程同步:交替打印A、B LockSupport实现

一 问题概述 线程或者进程之间有两种关系 同步和互斥,我们通常实现同步方法是使用线程的等待唤醒机制,而等待唤醒机制的使用是建立在互斥的继承上的.但是同步线程并不一定是必须要实现互斥的.比如一个线程打印A,一个线程打印B.这两个线程就没有互斥关系,但是提出这么个需求:交替打印A.B .我们一般的解决方案,往往要使用wait()/notify机制. 二 LockSupport 介绍 LockSupport作为一个工具类,主要学习它的方法. park():在线程内调用,表示当前线程自我阻塞,直到获得许