//2019/06/13 本周HT面试遇到的问题,答得不是很好,自己重新做一下。面试只需要写出线程间通信的方式,
//我当时大致知道思路,因为之前看过马士兵老师的多线程视频,但是代码写出来估计编译都是报错的。

//线程通信方式
public class ThreadTwo {

   //内部静态类,类去实现Runnable接口,obj通过构造方法,是希望这两个方法被一个参数锁住
public static class PrintABC implements Runnable{
Object o = null;

public PrintABC(Object o) {
this.o = o;
}

@Override
public void run() {
synchronized (o){
char ch = 'A';
for(int i=0;i<26;i++) {
            //ascii码吧
System.out.print((char) (ch + i));
            //之前这个写在了wait()方法后面,导致一直睡下去,无法唤醒了
o.notifyAll();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
}

private static class Print123 implements Runnable{

Object o = null;

public Print123(Object o) {
this.o = o;
}

@Override
public void run() {
synchronized (o) {
for(int i=1;i<=52;i++) {
System.out.print(i);
if (i % 2 == 0) {
o.notifyAll();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
}
}

public static void main(String[] args) {
     //同一把锁
Object o = new Object();
new Thread(new Print123(o)).start();
new Thread(new PrintABC(o)).start();
}

}

//互斥锁方式
public class ThreadTwoLock {

static class PrintAll{

Lock lock = new ReentrantLock();
Condition conChar = lock.newCondition();
Condition conNum = lock.newCondition();

boolean flag = true;

public void printABC(){
        //二话不说,方法一上来先锁上
lock.lock();

try {

for (int i = 0; i < 26; i++) {
            //每次打印之前判断自己还能不能打印,flag==true表示打印字母的要等下,让打印数字的来
if (flag) {
conChar.await();
}
char a = 'A';
System.out.print((char) (a + i));
            //打印了一个字母,让当前打印字母的线程停下,flag=true
flag=true;
            //唤醒打印数字的线程
conNum.signal();

}
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
            //释放锁
lock.unlock();
}

}

public void print123(){

lock.lock();

try {

for (int i = 1; i <= 52; i++) {
if(!flag) {
conNum.await();
}
System.out.print(i);
if (i % 2 == 0) {
flag = false;
conChar.signal();

}
}

} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

public static void main(String[] args) {
final PrintAll pa = new PrintAll();
    //main方法里就负责创建和启动线程,别的啥也不做
new Thread(()->{
pa.printABC();
}).start();
new Thread(()->{
pa.print123();
}).start();

}
}

运行结果:
12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z

2种方式(线程间通信/互斥锁)实现两个线程,一个线程打印1-52,另一个线程打印字母A-Z,打印顺序为12A34B56C......5152Z的更多相关文章

  1. communication between threads 线程间通信 Programming Concurrent Activities 程序设计中的并发活动 Ada task 任务 Java thread 线程

    Computer Science An Overview _J. Glenn Brookshear _11th Edition activation 激活 parallel processing 并行 ...

  2. java多线程系列5-死锁与线程间通信

    这篇文章介绍java死锁机制和线程间通信 死锁 死锁:两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象. 同步代码块的嵌套案例 public class MyLock { // 创建两 ...

  3. Java 里如何实现线程间通信(转载)

    出处:http://www.importnew.com/26850.html 正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程 ...

  4. Java 如何实现线程间通信?(notify、join、CountdownLatch、CyclicBarrier、FutureTask、Callable )

    转自:https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247486499&idx=1&sn=d3f2d6959df ...

  5. Java 里如何实现线程间通信

    正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点:thread.join(), object.w ...

  6. Java 如何实现线程间通信

    正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点: thread.join(), object. ...

  7. 【转】Java里如何实现线程间通信

    正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点:thread.join(), object.w ...

  8. Java 中如何实现线程间通信

    世界以痛吻我,要我报之以歌 -- 泰戈尔<飞鸟集> 虽然通常每个子线程只需要完成自己的任务,但是有时我们希望多个线程一起工作来完成一个任务,这就涉及到线程间通信. 关于线程间通信本文涉及到 ...

  9. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

随机推荐

  1. Navicat Premium 15破解

    https://pan.baidu.com/s/1bJ1BJUcL6cFd4StB5Qn_hQ 提取码:1314 拿走,不谢!!!

  2. pytest文档47-allure报告添加用例失败截图

    前言 使用 selenium 做 web 自动化的时候,很多小伙伴希望用例失败的时候能截图,把异常截图展示到allure报告里面. pytest 有个很好的钩子函数 pytest_runtest_ma ...

  3. wifi - 无线相关命令

    1.Linux环境下的无线相关操作命令 interface 指代当前网卡 一般是 wifi0 ,  eth0 ,  ath1等 ifconfig - 常用查看网络设定及控制网卡(Windows下是ip ...

  4. docker安装部署neo4j

    docker部署neo4j 环境:ubuntu16.04LTS docker安装 详见:菜鸟教程(docker安装) docker国内镜像源配置 第一步,进入阿里云,登陆后点击左侧的镜像加速,生成自己 ...

  5. Linux用户和组管理命令-用户删除userdel

    删除用户 userdel 可删除Linux 用户 格式: userdel [OPTION]... Login 常见选项: -f, --force 强制 -r, --remove 删除用户家目录和邮箱 ...

  6. fish_redux使用详解---看完就会用!

    说句心里话,这篇文章,来来回回修改了很多次,如果认真看完这篇文章,还不会写fish_redux,请在评论里喷我. 前言 来学学难搞的fish_redux框架吧,这个框架,官方的文档真是一言难尽,比fl ...

  7. git学习(九) idea git stash操作

    在前面说过,git stash 命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容:git stash 作用的范围包括工作区和暂存区中的内容,没 ...

  8. int是java.lang包中可用的类的名称

    int是java.lang包中可用的类的名称(x) int为基本数据类型,不是类

  9. 自动识别PC端、移动端,并跳转

    PC端和移动端代码是分开的,各有一套代码的情况下: 在PC端的HTML文件head标签中间添加一段自动识别移动端的JavaScript代码: <script type="text/ja ...

  10. Redis中的跳表

    date: 2020-10-15 14:58:00 updated: 2020-10-19 17:58:00 Redis中的跳表 参考网址1 参考网址2 redis 数据类型 zset 实现有序集合, ...