Java多线程实战之交叉打印的两种方法

要求效果:先打印5次“printA…”,再打印5次“printB…”,每次打印间隔1秒,重复循环20次

方式一:使用wait()和notifyAll()方法

public class MyService {
 private volatile boolean flag = false;
 public synchronized void printA() {
 try {
  while (flag) {
  wait();
  }
  for (int i = 0; i < 5; i++) {
  System.out.println("printA...");
  TimeUnit.SECONDS.sleep(1);
  }
  flag = true;
  notifyAll();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 }
 public synchronized void printB() {
 try {
  while (!flag) {
  wait();
  }
  for (int i = 0; i < 5; i++) {
  System.out.println("printB...");
  TimeUnit.SECONDS.sleep(1);
  }
  flag = false;
  notifyAll();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 }
}
public class BackupA implements Runnable {
 private MyService myService;
 public BackupA(MyService myService) {
 super();
 this.myService = myService;
 }
 @Override
 public void run() {
 myService.printA();
 }
}
public class BackupB implements Runnable {
 private MyService myService;
 public BackupB(MyService myService) {
 super();
 this.myService = myService;
 }
 @Override
 public void run() {
 myService.printB();
 }
}
public class Run {
 public static void main(String[] args) {
 MyService myService = new MyService();
 for (int i = 0; i < 20; i++) {
  new Thread(new BackupA(myService)).start();
  new Thread(new BackupB(myService)).start();
 }
 }
}

方式二:使用await()和signalAll()方法

public class MyService {
 private Lock lock = new ReentrantLock();
 private Condition condition = lock.newCondition();
 private boolean flag = false;
 public void printA() {
 try {
  lock.lock();
  while (flag) {
  condition.await();
  }
  for (int i = 0; i < 5; i++) {
  System.out.println("printA...");
  TimeUnit.SECONDS.sleep(1);
  }
  flag = true;
  condition.signalAll();
 } catch (InterruptedException e) {
  e.printStackTrace();
 } finally {
  lock.unlock();
 }
 }
 public void printB() {
 try {
  lock.lock();
  while (!flag) {
  condition.await();
  }
  for (int i = 0; i < 5; i++) {
  System.out.println("printB...");
  TimeUnit.SECONDS.sleep(1);
  }
  flag = false;
  condition.signalAll();
 } catch (InterruptedException e) {
  e.printStackTrace();
 } finally {
  lock.unlock();
 }
 }
}
public class ThreadA implements Runnable {
 private MyService myService;
 public ThreadA(MyService myService) {
 super();
 this.myService = myService;
 }
 @Override
 public void run() {
 myService.printA();
 }
}
public class ThreadB implements Runnable {
 private MyService myService;
 public ThreadB(MyService myService) {
 super();
 this.myService = myService;
 }
 @Override
 public void run() {
 myService.printB();
 }
}
public class Run {
 public static void main(String[] args) {
 MyService myService = new MyService();
 for (int i = 0; i < 20; i++) {
  new Thread(new ThreadA(myService)).start();
  new Thread(new ThreadB(myService)).start();
 }
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • java线程池使用后到底要关闭吗

    线程池做什么 网络请求通常有两种形式: 第一种,请求不是很频繁,而且每次连接后会保持相当一段时间来读数据或者写数据,最后断开,如文件下载,网络流媒体等. 另一种形式是请求频繁,但是连接上以后读/写很少量的数据就断开连接.考虑到服务的并发问题,如果每个请求来到以后服务都为它启动一个线程,那么这对服务的资源可能会造成很大的浪费,特别是第二种情况. 因为通常情况下,创建线程是需要一定的耗时的,设这个时间为T1,而连接后读/写服务的时间为T2,当T1>>T2时,我们就应当考虑一种策略或者机制来控制,使

  • Java多线程实战之单例模式与多线程的实例详解

    1.立即加载/饿汉模式 // 立即加载/饿汉模式 public class MyObject { private static final MyObject myObject = new MyObject(); private MyObject() { } public static MyObject getInstance() { return myObject; } } 立即加载/饿汉模式是在类创建的同时已经创建好一个静态的对象供系统使用,不存在线程安全问题 2.延迟加载/懒汉模式 // 延

  • 实例分析java开启线程的方法

    有时候我们在使用java编程的时候,想启动线程,怎么启动呢,下面来分享一下方法 第一步在我们的电脑上打开eclipse,创建一个java项目,并创建三个类,Test是测试Runnable类实现的多线程程序类,DoSomething是实现Runnable接口的多线程类,TestThread是测试继承Thread类实现的多线程程序类,如下图所示: 第二步我们首先看一下DoSomething类,实现了Runnable接口,成为线程类,并在run方法中进行双层循环打印姓名和数字,如下图所示: 第三步我们

  • Java实现指定线程执行顺序的三种方式示例

    本文实例讲述了Java实现指定线程执行顺序的三种方式.分享给大家供大家参考,具体如下: 方法一:通过共享对象锁加上可见变量来实现. public class MyService { private volatile int orderNum = 1; public synchronized void methodA() { try { while (orderNum != 1) { wait(); } for (int i = 0; i < 2; i++) { System.out.printl

  • Java线程公平锁和非公平锁的差异讲解

    公平锁,顾名思义,它是公平的,可以保证获取锁的线程按照先来后到的顺序,获取到锁. 非公平锁,顾名思义,各个线程获取到锁的顺序,不一定和它们申请的先后顺序一致,有可能后来的线程,反而先获取到了锁. 在实现上,公平锁在进行lock时,首先会进行tryAcquire()操作.在tryAcquire中,会判断等待队列中是否已经有别的线程在等待了.如果队列中已经有别的线程了,则tryAcquire失败,则将自己加入队列.如果队列中没有别的线程,则进行获取锁的操作. /** * Fair version o

  • Java多线程编程实战之模拟大量数据同步

    背景 最近对于 Java 多线程做了一段时间的学习,笔者一直认为,学习东西就是要应用到实际的业务需求中的.否则要么无法深入理解,要么硬生生地套用技术只是达到炫技的效果. 不过笔者仍旧认为自己对于多线程掌握不够熟练,不敢轻易应用到生产代码中.这就按照平时工作中遇到的实际问题,脑补了一个很可能存在的业务场景: 已知某公司管理着 1000 个微信服务号,每个服务号有 1w ~ 50w 粉丝不等.假设该公司每天都需要将所有微信服务号的粉丝数据通过调用微信 API 的方式更新到本地数据库. 需求分析 对此

  • java基于C/S结构实现多线程聊天室

    本文实例为大家分享了java基于C/S结构实现多线程聊天室的具体代码,供大家参考,具体内容如下 主要实现的功能: 服务器端建立ServerSocket阻塞监听来自客户端的Socket连接,并为之开辟一个新的线程 读取来自该连接的数据,广播每一个客户端数据,这里简单地使用一个链表保存所有来自客户端的所有Socket连接 客户端连接上服务器端后主要有两个线程在工作: 主线程:不断获取键盘的输入并写入该Socket中传输给服务器 副线程:不断从服务器Socket流中读取传来的数据,打印到屏幕上. 服务

  • Java多线程实战之交叉打印的两种方法

    要求效果:先打印5次"printA-",再打印5次"printB-",每次打印间隔1秒,重复循环20次 方式一:使用wait()和notifyAll()方法 public class MyService { private volatile boolean flag = false; public synchronized void printA() { try { while (flag) { wait(); } for (int i = 0; i < 5;

  • Java 在PDF中绘制形状的两种方法

    在我们编辑PDF文档的过程中,有时候需要在文档中添加一些如多边形.矩形.椭圆形之类的图形,而Free Spire PDF for Java 则正好可以帮助我们在Java程序中通过代码在PDF文档中绘制形状,以及设置形状边线颜色和填充色. Jar包导入 方法一:下载Free Spire.PDF for Java包并解压缩,然后将lib文件夹下的Spire.Pdf.jar包作为依赖项导入到Java应用程序中 方法二:直接通过Maven仓库安装JAR包,配置pom.xml文件的代码如下: <repos

  • 使用Java构造和解析Json数据的两种方法(详解二)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Json数据的方法

  • 使用Java构造和解析Json数据的两种方法(详解一)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Json数据的方法

  • Java 在PDF中添加条形码的两种方法

    条形码,是由宽度不等的多个黑条和空白所组成,用以表达一组信息的图形标识符.通过给文档添加条形码,可以直观,快捷地访问和分享一些重要的信息.本文就将通过使用Java程序来演示如何在PDF文档中添加Codebar.Code128A和Code39条形码.除此之外,还可支持创建Code11.Code128B.Code32.Code39 Extended .Code93和Code93 Extended条形码. 使用工具:Free Spire.PDF for Java(免费版) Jar文件获取及导入: 方法

  • Java字符串的压缩与解压缩的两种方法

    应用场景 当字符串太长, 需要将字符串值存入数据库时,如果字段长度不够,则会出现插入失败: 或者需要进行Http传输时,由于参数长度过长造成http传输失败等. 字符串压缩与解压方法 方法一:用 Java8中的gzip /** * 使用gzip压缩字符串 * @param str 要压缩的字符串 * @return */ public static String compress(String str) { if (str == null || str.length() == 0) { retu

  • Java多线程下解决资源竞争的7种方法详解

    前言 一般情况下,只要涉及到多线程编程,程序的复杂性就会显著上升,性能显著下降,BUG出现的概率大大提升. 多线程编程本意是将一段程序并行运行,提升数据处理能力,但是由于大部分情况下都涉及到共有资源的竞争,所以修改资源 对象时必须加锁处理.但是锁的实现有很多种方法,下面就来一起了解一下在C#语言中几种锁的实现与其性能表现. 一.c#下的几种锁的运用方式 1.临界区,通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. private static object obj = n

  • Java实现掷骰子控制台和窗体两种方法

    本文实例为大家分享了Java控制台和窗体实现掷骰子的具体代码,供大家参考,具体内容如下 程序目标:同时3掷骰子,让骰子转动若干次后停下来的正面朝上的数字之和大于9 则为大,小于等于9则为小 用于需要提前选择押大还是小,程序结束返回是否押中的结果. 1.掷骰子控制台实现 本程序分为三层: 表示层 :用类Player2 实现 业务逻辑层:类DiceGame2 实现 数据/技术服务层:类Dice2 实现 Dice2 类 实现Runnable接口,重新run()方法来设置每个骰子转动10次 ,并在停下来

  • Java中启动线程start和run的两种方法

    一.区别 Java中启动线程有两种方法,继承Thread类和实现Runnable接口,由于Java无法实现多重继承,所以一般通过实现Runnable接口来创建线程.但是无论哪种方法都可以通过start()和run()方法来启动线程,下面就来介绍一下他们的区别. start方法: 通过该方法启动线程的同时也创建了一个线程,真正实现了多线程.无需等待run()方法中的代码执行完毕,就可以接着执行下面的代码.此时start()的这个线程处于就绪状态,当得到CPU的时间片后就会执行其中的run()方法.

  • java创建线程的两种方法区别

    在Java中创建一个线程有两种方法:继承Thread类和实现Runnable接口. 下面通过两个例子来分析两者的区别: 1)继承Thread类 public class TestThread extends Thread { int count = 3; public TestThread(String ThreadName) { super(ThreadName); } @Override public void run() { for (int i = 0; i < 10; i++) if

随机推荐