1.

创建两个线程,一个线程打印1---25
一个线程打印A-Z
输出效果是12A34B56C......5152Z

第一版不符合我们的要求(因为无法确定哪个线程先执行):

public class MyTest {public static void main(String[] args) {// 创建两个线程,一个线程打印 1---52//一个线程打印 A-Z//输出效果是 12A34B56C.......5152Z//第一版不是很符合我们的要求MyObject obj = new MyObject();NumberRunnable numberRunnable = new NumberRunnable(obj);CharRunnable charRunnable = new CharRunnable(obj);Thread th1 = new Thread(numberRunnable);Thread th2 = new Thread(charRunnable);th1.start();th2.start();}
}
/*
*在某个线程方法中对wait()和notify()的调用必须指定一个Object对象,而且该线程必须拥有该Object对象的monitor。而获取对象monitor最简单的办法就是,在对象上使用synchronized关键字。当调用wait()方法以后,该线程会释放掉对象锁,并进入sleep状态。而在其它线程调用notify()方法时,必须使用同一个Object对象,notify()方法调用成功后,所在这个对象上的相应的等侍线程将被唤醒。
对于被一个对象锁定的多个方法,在调用notify()方法时将会任选其中一个进行唤醒,而notifyAll()则是将其所有等待线程唤醒。
*
* notify()需要在同步方法或同步块中调用,即在调用前,线程必须获得该对象的对象级别锁
在调用wait()方法之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait方法。
*
* */
class MyObject{}
class NumberRunnable implements Runnable{private MyObject obj;public NumberRunnable(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 1; i <= 52; i++) {synchronized (obj){System.out.println(i); //1 2if(i%2==0){obj.notify(); //唤醒等待的线程try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}
}
class CharRunnable implements Runnable{private MyObject obj;public CharRunnable(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i ='A'; i <='Z'; i++) {synchronized (obj){System.out.println((char) i);obj.notify();try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}
}

定义一个类型作为标记:

public class MyTest {public static void main(String[] args) {// 创建两个线程,一个线程打印 1---52//一个线程打印 A-Z//输出效果是 12A34B56C.......5152ZMyObject obj = new MyObject();NumberRunnable numberRunnable = new NumberRunnable(obj);CharRunnable charRunnable = new CharRunnable(obj);Thread th1 = new Thread(numberRunnable);Thread th2 = new Thread(charRunnable);th2.start();th1.start();}
}/*
*在某个线程方法中对wait()和notify()的调用必须指定一个Object对象,而且该线程必须拥有该Object对象的monitor。而获取对象monitor最简单的办法就是,在对象上使用synchronized关键字。当调用wait()方法以后,该线程会释放掉对象锁,并进入sleep状态。而在其它线程调用notify()方法时,必须使用同一个Object对象,notify()方法调用成功后,所在这个对象上的相应的等侍线程将被唤醒。
对于被一个对象锁定的多个方法,在调用notify()方法时将会任选其中一个进行唤醒,而notifyAll()则是将其所有等待线程唤醒。
*
* notify()需要在同步方法或同步块中调用,即在调用前,线程必须获得该对象的对象级别锁
在调用wait()方法之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait方法。
*
* */class MyObject{// boolean  flag;public int flag=1; //int 类型作为标记,可以多标记一下情况
}class NumberRunnable implements Runnable{private MyObject obj;public NumberRunnable(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 1; i <= 52; i++) {synchronized (obj){if(obj.flag!=1){ //1!=1 falsetry {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}//开始打印System.out.println(i);if(i%2==0){obj.flag=2;obj.notify(); //唤醒等待的线程}}}}
}class CharRunnable implements Runnable{private MyObject obj;public CharRunnable(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i ='A'; i <='Z'; i++) {synchronized (obj){if(obj.flag!=2){ //1!=2 truetry {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println((char) i);//修改标记obj.flag=1;//唤醒等待的线程obj.notify();}}}
}

2.

两个线程,一个线程打印100个A,一个线程打印100个B
效果就是 AB AB AB AB......

public class MyTest {public static void main(String[] args) {//两个线程 一个线程打印100个A 1个线程打印 100个B//效果就是AB AB AB AB...MyObject obj = new MyObject();AThread th1 = new AThread(obj);BThread th2 = new BThread(obj);th2.start();th1.start();}
}class MyObject {// boolean  flag;public int flag = 1; //int 类型作为标记,可以多标记一下情况
}class AThread extends Thread {private MyObject obj;public AThread(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {synchronized (obj) {if (obj.flag != 1) {try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("A");obj.flag = 2;obj.notify();}}}
}class BThread extends Thread {private MyObject obj;public BThread(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {synchronized (obj) {if (obj.flag != 2) {try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("B");obj.flag = 1;obj.notify();}}}
}

3.

三个线程 一个线程打印100个A 1个线程打印 100个B  1个线程打印 100个C
效果:ABCABCABCABC

public class MyTest {public static void main(String[] args) {/**  创建三个线程:一个线程打印 100个A,一个线程打印 100 个 B ,一个线程打印 100个C*  输出效果:ABC ABC ABC.....交替打印* */MyObject obj = new MyObject();AThread th1 = new AThread(obj);BThread th2 = new BThread(obj);CThread th3 = new CThread(obj);th1.start();th3.start();th2.start();}
}class MyObject {static int flag = 1;
}class AThread extends Thread {private MyObject obj;public AThread(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {synchronized (obj) {//使用while来判断,而不使用if防止虚假唤醒while (obj.flag != 1) {try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("A");obj.flag = 2;// Thread.sleep(1000); 可以等1秒再唤醒对方obj.notifyAll(); //唤醒所有等待的线程。}}}
}class BThread extends Thread {private MyObject obj;public BThread(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {synchronized (obj) {while (obj.flag != 2) {try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("B");obj.flag = 3;obj.notifyAll();//唤醒所有等待的线程。}}}
}class CThread extends Thread {private MyObject obj;public CThread(MyObject obj) {this.obj = obj;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {synchronized (obj) {while (obj.flag != 3) {try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("C");obj.flag = 1;obj.notifyAll();//唤醒所有等待的线程。}}}
}

把if改成while防止线程假唤醒或伪唤醒:

多线程练习题(12A34B......)(ABAB......)(ABCABA......)相关推荐

  1. java 多线程 选择题_Java多线程之三道多线程练习题

    三道多线程练习题 接下来,我们来做三道题: 第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个 ...

  2. python 选择题 多线程_python多线程练习题

    python多线程练习题 多线程练习题目,涉及知识点较多,属于很好的练习题. 题目要求 通过多线程实现类似linux中的>>功能,也就是将日志记录到指定的文件中. 题目分析 基本为main ...

  3. 【Java】集合+I/O流+多线程の练习题+面试题

    一. Collection Collection 和 Collections的区别 答:Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections是针对集 ...

  4. 二十六、多线程练习题

    第1关:顺序输出 任务描述 本关任务:利用多线程相关知识控制三个线程,依照先后顺序顺序输出. 相关知识 (略) 编程要求 请仔细阅读右侧代码,在 Begin-End 区域内进行代码补充,使线程依照先后 ...

  5. Java高级特性 - 多线程练习题

    第1关:顺序输出 任务描述 本关任务:利用多线程相关知识控制三个线程,依照先后顺序顺序输出. 相关知识(略) 编程要求 请仔细阅读右侧代码,在 Begin-End 区域内进行代码补充,使线程依照先后顺 ...

  6. 头歌Educoder——Java高级特性 - 多线程练习题

    文章目录 第1关:顺序输出 任务描述 相关知识(略) 编程要求 测试说明 代码示例 第2关:售票窗口 任务描述 相关知识(略) 编程要求 测试说明 代码示例 Station.java Task.jav ...

  7. java使用线程求素数和1000个0~0.9随机数_求素数(多线程练习题)

    编写一个有两个线程的程序,第一个线程用来计算2-100000之间的素数的个数, 第二个线程用来计算100000-200000之间的素数的个数,最后输出结果. 代码实现: package com.thr ...

  8. c语言多进程编写龟兔赛跑程序,龟兔赛跑(多线程练习题)

    1.龟兔赛跑新规: 规则:龟兔同时起步,终点为100米,兔子跑步的能力强,乌龟跑步的能力弱(优先级的设置) 途中:        1.兔子跑到40米的时候,看不见乌龟小睡10毫秒,醒来接着跑 2.兔子 ...

  9. java学习之路 之 多线程练习题

    package com.atguigu.javase.thread;/*** 创建并启动一个线程的方法* 1) 实现接口的方式* 1) 写一个具体类, 实现Runnable接口, 并实现其中的run方 ...

最新文章

  1. android组合动画还原,Android - Fragment,View动画,组合动画,属性动画
  2. 决策树Decision Tree 及实现
  3. 【知识星球】颜值,自拍,美学三大任务简介和数据集下载
  4. 服务器2012r2系统安装数据库,数据库图文详解Windows Server2012 R2中安装SQL Server2008...
  5. nuget pack
  6. 加载gif动图_【知乎编辑技巧】GIF动图 的插入 2020.05
  7. 前端学习(2110):组件化得开发和实现步骤
  8. DB2常用傻瓜问题1000问(之一)
  9. VB.NET Visual Basic
  10. kotlin android 镜像,【54】Kotlin android Anko 神兵利器
  11. JavaScript 中的函数式编程实践
  12. unix网络编程各种TCP客户-服务器程序设计实例(三)
  13. (转)wuauclt.exe病毒解决方案
  14. Unity 相机被遮挡的判断与处理
  15. terraform 腾讯云_使用Terraform优化云成本的权威指南
  16. 044_Unicode对照表十
  17. 手机游戏软件开发的前景 The future of development of game software on mobiles
  18. CaptchaBuilder验证码不显示
  19. 关于win7 出现两个本地连接不能上网的问题?
  20. [架构之路-5]:架构师 - 中国计算机技术职业资格(软考)考试是如何定义系统架构师?

热门文章

  1. python如何实现飞机上下移动_python实现飞机大战
  2. 2019.2.27热身赛
  3. 百度mip推送工具_百度 MIP 功能正式下线,继熊掌号之后又黄一个项目
  4. ECMAScript 6(5)字符串与Unicode编码大于65535的字符
  5. 3、宽带对称式高回退Doherty放大器ADS仿真(带版图)
  6. 制作柔性电路的常用方法
  7. 微型计算机原理及应用是啥,微型计算机原理及应用(一)
  8. WPF实现聚光灯查看内容特效
  9. 建数据库oracle 01031,DBCA创建ASM数据库时遇到ORA-01031
  10. cas cvm服务器虚拟化安装虚拟机,CAS系统如何安装虚拟机