概述

作为程序员经常在面试的时候遇到多线程的问题,我印象比较深刻的就是下面这道题:写两个线程,一个线程打印 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. Linux系统 磁盘IO过高排查总结

    最近做的一个电商网站因为磁盘 I/O 过高导致访问速度奇慢,问题存在两个月有余未得到解决办法.此次排查原因的经验可以作下次问题的参考. 1.会看懂 top 系统命令出来的各项参数.此次是无意中发现 u ...

  2. 旧版本firefox添加扩展addons的地址

    不要在 firefox 本身的addons 中去查找, 搜索, 那个是搜索不到的, 因为那个是针对 最新版的, 旧版本的很多插件都不能用, 被移除了, 要在 那个专门 提供 插件的站点中去寻找扩展 h ...

  3. Java基础知识盘点(二)- 集合篇

    List和Set区别 List和Set都是继承Collection接口 List特点:元素有放入顺序,元素可重复 Set特点:元素无放入顺序,元素不可重复 Set和List对比: Set:检索元素效率 ...

  4. js原型和原型链理解到面向对象

    一.js中的两种对象,普通对象和函数对象 var obj1 = {}; var obj2 =new Object(); var obj3 = new obj1(); function fun1(){} ...

  5. Oracle 创建,查询,删除 job

    一 . 创建job 1. 通过创建存储过程的方式创建job 调用该存储过程使其开始执行  call PRO_DSJ_XJTJ_JOB(); create or replace procedure PR ...

  6. pytest--fixture参数化的实现方式和执行顺序

    之前看到fixture函数可以通过添加,params参数来实现参数化,后续看到了悠悠 的博客,可以通过@pytest.mark.parametrize来实现,现在做一个总结 实现方式一 通过param ...

  7. 禁止root登陆sshd/并修改默认端口号

    1,新建一个用户: #useradd xxx 2,为新用户设置密码: #passwd xxx 3,修改sshd配置文件 #vi /etc/ssh/sshd_config 查找“#PermitRootL ...

  8. Unity --- 在原目录中,将选中的Texture剥离为rgb和alpha

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; us ...

  9. @RequestMapping的Ant风格URL

    Ant风格资源地址支持3中匹配符 ? 匹配文件名中一个字符. *   匹配 文件名中任意字符 **  匹配多层路径 例如 /hello/*/myspring 匹配 /hello/abc/mysprin ...

  10. WARING

    每一道题都先手玩样例! 认真读一下每一档数据,仔细计算每一档可以拿的分数! 读完题目后,把所有能想到的思路写在纸上. 最优化题目考虑dp和贪心两种方法 字符串题目前缀考虑trie树,后缀考虑fail树 ...