概述

作为程序员经常在面试的时候遇到多线程的问题,我印象比较深刻的就是下面这道题:写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。看这个题目已经说得很清楚了,要用两个线程交替打印出12A....Z,我相信如每个线程单独打印的话肯定没问题,但是要交替打印,就需要两个线程互相合作,就需要通信。

代码实现

方法一

 package com.cfxmn.springboot.springbootDemo.test;

 // 使用多线程打印12A34B.......5152Z
public class MainTest2 {
public static void main(String[] args) {
Object obj = new Object(); // 共享资源,实现线程间的通信
Thread printNum = new Thread(new PrintNum(obj));
Thread printChar = new Thread(new PrintChar(obj));
printNum.start();
printChar.start();
}
} // 打印数字
class PrintNum implements Runnable { private Object object; public PrintNum (Object obj) {
this.object = obj;
} @Override
public void run() {
synchronized (object) {
for (int i=1;i<=52;i++) {
System.out.print(i);
if (i % 2 == 0) {
object.notifyAll(); // 先唤醒所有线程
try {
object.wait(); // 阻塞当前线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} } // 打印字母
class PrintChar implements Runnable { private Object object; public PrintChar (Object obj) {
this.object = obj;
} @Override
public void run() {
synchronized (object) {
for (int i=65;i<=90;i++) {
System.out.print((char)i);
object.notifyAll(); // 先唤醒所有线程
try {
object.wait(); // 阻塞当前线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} }

运行结果:

12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z

上面我是使用了wait,notifyAll,synchronized实现的,是不是还有其他的实现方法呢?

方法二

 package com.cfxmn.springboot.springbootDemo.test;

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; //使用多线程打印12A34B.......5152Z
public class MainTest3 { private Lock lock = new ReentrantLock();
private Condition printNum = lock.newCondition();
private Condition printchar = lock.newCondition(); public static void main(String[] args) {
MainTest3 test = new MainTest3();
Thread printNum = new Thread(test.new PrintNumt());
Thread printChar = new Thread(test.new PrintChart());
printChar.start();
printNum.start(); } //打印数字
class PrintNumt implements Runnable { @Override
public void run() { for (int i = 1; i <= 52; i++) {
lock.lock();
try {
printchar.signalAll();
System.out.print(i);
if (i % 2 == 0) {
printNum.await();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
} } //打印字母
class PrintChart implements Runnable { @Override
public void run() { for (int i = 0; i < 26; i++) {
lock.lock();
try {
printNum.signalAll();
System.out.print((char)(i + 'A'));
printchar.await();
} catch (Exception e) {
e.printStackTrace(); } finally {
lock.unlock();
}
} } }
}

这边使用了lock,和condition来实现,它的两个方法signalAll,await相当于notifyAll,wait,效果是一样的。

Java面试题之多线程打印的更多相关文章

  1. java面试题:多线程交替输出偶数和奇数

    一个面试题:实现两个线程A,B交替输出偶数和奇数 问题:创建两个线程A和B,让他们交替打印0到100的所有整数,其中A线程打印偶数,B线程打印奇数 这个问题配合java的多线程,很多种实现方式 在具体 ...

  2. java面试题:多线程与并发

    多线程 关键词:线程池 Q:如何新建一个线程? 继承Thread,或者实现Runnable接口,或者通过Callable接口实现. Q:Callable怎么用? Callable可以作为FutureT ...

  3. Java面试题(多线程篇)

    多线程 35.并行和并发有什么区别? 1.并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生. 2.并行是在不同实体上的多个事件,并发是在同一实体上的多个事件. 3.在 ...

  4. Java面试题之多线程同步和互斥有几种实现方法,都是什么?

    线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另外一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒. 线程互斥是指对于共享的进程系统资源,每个线程访问时的排他 ...

  5. Java面试中的多线程问题

    很多核心 Java 面试题来源于多线程(Multi-Threading)和集合框架(Collections Framework),理解核心线程概念时,娴熟的实际经验是必需的.这篇文章收集了 Java ...

  6. 2019百度阿里Java面试题(基础+框架+数据库+分布式+JVM+多线程)

    前言 很多朋友对面试不够了解,不知道如何准备,对面试环节的设置以及目的不够了解,因此成功率不高.通常情况下校招生面试的成功率低于1%,而社招的面试成功率也低于5%,所以对于候选人一定要知道设立面试的初 ...

  7. Java面试题:Java中怎么样实现多线程

    方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可. 下面是一个例子: public class MyThrea ...

  8. java实现 历届试题 蓝桥杯 打印十字图

    历届试题 打印十字图 题目描述 小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg) 对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数. 为了能 ...

  9. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

随机推荐

  1. Python模块 3

    time模块 在计算中时间共有三种方式: 1.时间戳: 通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们运行“type(time.time())”,返回的是flo ...

  2. UVA11996 Jewel Magic

    思路 splay维护序列的hash值即可 因为有rev操作,还要维护反串的hash值 代码 #include <cstdio> #include <cstring> #incl ...

  3. mongodb常用的sql语句总结

    本文为博主原创,转载请注明出处: 1 .  查询所有 db.getCollection('CollectionName').find() 2.根据条件查询 db.getCollection('Coll ...

  4. HDU 1067 Gap

    HDU 1067 Gap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)   P ...

  5. 前端基础面试题(JS部分)

    1.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构? 基本数据类型:Undefined.Null.Boolean.Number.String 值类型:数值.布尔值.null.und ...

  6. lua相关的小知识

    lua的特性 1. 轻量级:一标准的C语言编写原发开放,编译后仅仅100K,占用内存小: 2. 扩展性:Lua提供了非常已于使用的扩展口和机制: 3. 支持面向过程编程和函数式编程 lua的数据类型 ...

  7. Android 项目配置 gitlab-ci 持续集成

    一.项目根目录下创建一个 .gitlab-ci.yml 文件 然后在 .gitlab-ci.yml 中配置持续集成的脚本: 脚本配置详细可以看: Configuration of your jobs ...

  8. 第 9 章 数据管理 - 076 - 使用 Rex-Ray volume

    使用 Rex-Ray volume 在 docker1 或 docker2 上执行如下命令创建 volume: rexray volume create --size 2 'C:\share\myda ...

  9. js面向过程-经典选项卡

    源代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  10. Spring Boot 配置加载顺序详解

    使用 Spring Boot 会涉及到各种各样的配置,如开发.测试.线上就至少 3 套配置信息了.Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发.测试.线上环境使用不同的配置. 在 ...