概述

作为程序员经常在面试的时候遇到多线程的问题,我印象比较深刻的就是下面这道题:写两个线程,一个线程打印 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. Elasticsearch NEST 控制字段名称命名格式

    在使用NEST操作elasticsearch时,字段名会根据model中字段,默认为首字母小写. 如果需要调整NEST的默认明个规则,可以在 ConnectionSettings中进行自定义. var ...

  2. 【搬运工】修改mysql数据库的时区

    转载:https://blog.csdn.net/huangyuehong914/article/details/81742039 --------------------- ------------ ...

  3. sql学习书籍

    SQL 入门 在准备成为MySQL DBA之前,能熟练的编写SQL是一个必要条件.exists 和 join之间的等价转换:基本的行列转换:SQL 循环等的熟练掌握对之后的运维和调优工作都有很大的帮助 ...

  4. AT2412 最大の和

    传送门 思路: 线段树暴力枚举区间,查询最大区间和. Code: #include<iostream> #include<cstdio> #include<algorit ...

  5. Hash索引和BTree索引区别【转】

    索引是帮助mysql获取数据的数据结构.最常见的索引是Btree索引和Hash索引. 不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引:而Mermory默认的索引是 ...

  6. JQurey 添加和删除元素

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> ...

  7. toFixed()精度丢失;复选框全选、取消

    一.精度丢失和重写toFixed()函数 1.重写toFixed() Number.prototype.toFixed = function(length){ var carry = 0; //存放进 ...

  8. cron定时任务

    1.确认系统安装了cron rpm -aq | grep crontabs 2.认识cron时间格式 3.生成定时任务 crontab -e #进入任务命令编辑模式 30 7,12,20 * * * ...

  9. bilinear pooling

    一.双线性汇合的计算过程: 第一步,计算Gram 矩阵: 对于一组H×W×D的feature maps,$\boldsymbol{x}_{i} \in \mathbb{R}^{D}$是图像的深度描述, ...

  10. My Team——面向对象与软件工程实验三

    My Team 一.Name GDTX(团队成员姓氏的拼音首字母组成) 二.项目描述 微信小程序(小洁便签): 1,功能齐全:小洁便签具有大多数便签APP所具有的添加.查看.修改和删除便签内容以及插入 ...