Java多线程通信之两个线程分别打印AB各10次

一道经典的面试题目:两个线程,分别打印AB,其中线程A打印A,线程B打印B,各打印10次,使之出现ABABABABA.. 的效果

 1 package com.shangshe.path;
 2
 3 public class ThreadAB {
 4
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9
10         final Print business = new Print();
11
12         new Thread(new Runnable() {
13             public void run() {
14                 for(int i=0;i<10;i++) {
15                     business.print_A();
16                 }
17             }
18         }).start();
19
20         new Thread(new Runnable() {
21             public void run() {
22                 for(int i=0;i<10;i++) {
23                     business.print_B();
24                 }
25             }
26         }).start();
27
28     }
29 }
30 class Print {
31
32     private boolean flag = true;
33
34     public synchronized void print_A () {
35         while(!flag) {
36             try {
37                 this.wait();
38             } catch (InterruptedException e) {
39                 // TODO Auto-generated catch block
40                 e.printStackTrace();
41             }
42         }
43         System.out.print("A");
44         flag = false;
45         this.notify();
46     }
47
48     public synchronized void print_B () {
49         while(flag) {
50             try {
51                 this.wait();
52             } catch (InterruptedException e) {
53                 // TODO Auto-generated catch block
54                 e.printStackTrace();
55             }
56         }
57         System.out.print("B");
58         flag = true;
59         this.notify();
60     }
61 }

由上面的例子我们可以设计出3个线程乃至于n个线程的程序,下面给出的例子是3个线程,分别打印A,B,C 10次,使之出现ABCABC.. 的效果

 1 public class ThreadABC {
 2
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7
 8         final Print business = new Print();
 9
10         new Thread(new Runnable() {
11             public void run() {
12                 for(int i=0;i<100;i++) {
13                     business.print_A();
14                 }
15             }
16         }).start();
17
18         new Thread(new Runnable() {
19             public void run() {
20                 for(int i=0;i<100;i++) {
21                     business.print_B();
22                 }
23             }
24         }).start();
25
26         new Thread(new Runnable() {
27             public void run() {
28                 for(int i=0;i<100;i++) {
29                     business.print_C();
30                 }
31             }
32         }).start();
33
34     }
35 }
36 class Print {
37
38     private boolean should_a = true;
39     private boolean should_b = false;
40     private boolean should_c = false;
41
42     public synchronized void print_A () {
43         while(should_b || should_c) {
44             try {
45                 this.wait();
46             } catch (InterruptedException e) {
47                 // TODO Auto-generated catch block
48                 e.printStackTrace();
49             }
50         }
51         System.out.print("A");
52         should_a = false;
53         should_b = true;
54         should_c = false;
55         this.notifyAll();
56     }
57
58     public synchronized void print_B () {
59         while(should_a || should_c) {
60             try {
61                 this.wait();
62             } catch (InterruptedException e) {
63                 // TODO Auto-generated catch block
64                 e.printStackTrace();
65             }
66         }
67         System.out.print("B");
68         should_a = false;
69         should_b = false;
70         should_c = true;
71         this.notifyAll();
72     }
73
74     public synchronized void print_C () {
75         while(should_a || should_b) {
76             try {
77                 this.wait();
78             } catch (InterruptedException e) {
79                 // TODO Auto-generated catch block
80                 e.printStackTrace();
81             }
82         }
83         System.out.print("C");
84         should_a = true;
85         should_b = false;
86         should_c = false;
87         this.notifyAll();
88     }
89 }

再一次证明了软件工程的重要性了;在多线程程序中,应该说在程序中,我们应该把那些业务逻辑代码放到同一个类中,使之高内聚,低耦合

时间: 2024-12-18 12:35:02

Java多线程通信之两个线程分别打印AB各10次的相关文章

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

Java多线程基础:进程和线程之由来

在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通使用的,需要在实践中不断积累.由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助. 下面是本文的目录大纲: 一.操作系统中为什么会出现进程? 二.为什么会出现线程? 三.多线程并发 若有不正之处,请多多谅解并欢迎指正. 请尊重作者劳动成果,转载请标明原文地址:

Java多线程并发09——如何实现线程间与线程内数据共享

本文将为各位带来 Java 阻塞队列相关只是.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程间数据共享 Java 里面进行多线程通信的主要方式就是共享内存的方式,共享内存主要的关注点有两个:可见性和有序性原子性.Java 内存模型(JMM)解决了可见性和有序性的问题,而锁解决了原子性的问题,理想情况下我们希望做到"同步"和"互斥".有以下常规实现方法: 将数据抽象成一个类 将数据抽象成一个类,并将对这个数据的操作作为这个类的方法,这么设计可以和

Java多线程之~~~使用Exchanger在线程之间交换数据

在多线程中,两个线程之间交换数据是非常常见的情况,我们可以使用公共的数据结构,同样,Java也提供了很好 的类供我们使用,那就是Exchanger类,这个类可以帮助我们在两个线程之间同步数据结构,下面我们以这个类再来实 现一遍生产者消费者模型,貌似这个模型已经被写烂了. package com.bird.concursey.charpet5; import java.util.List; import java.util.concurrent.Exchanger; public class Pr

Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]

http://blog.csdn.net/a352193394/article/details/39503857 具体看 http://www.cnblogs.com/donaldlee2008/p/5290169.html java 线程池 并行 执行   http://www.cnblogs.com/donaldlee2008/p/5290169.html Java多线程之~~~使用Exchanger在线程之间交换数据 2014-09-23 20:48 1205人阅读 评论(0) 收藏 举报

Java多线程(四)、线程池(转)

Java多线程(四).线程池 分类: javaSE综合知识点 2012-09-19 17:46 3943人阅读 评论(1) 收藏 举报 系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似的是,线程池在系统启动时即创建大量空闲的线程,程序将一个Runnable对象传给线程池,线程池就会启动一条线程来执行该对象的run方法,当run方法执行结束后,该线

Java多线程(三)、线程同步(转)

Java多线程(三).线程同步 分类: javaSE综合知识点 2012-09-18 17:59 2400人阅读 评论(0) 收藏 举报 在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的控制吧. 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数

Java多线程(二)、线程的生命周期和状态控制(转)

Java多线程(二).线程的生命周期和状态控制 分类: javaSE综合知识点 2012-09-10 16:11 15937人阅读 评论(3) 收藏 举报 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadSt