public static Boolean isThreadA = true;
public static Boolean isThreadB = false;
public static Boolean isThreadC = false;
public static void main(String[] args) {
final PrintABC abc = new PrintABC();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (abc) {
while(!isThreadA) {
try {
abc.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print("A");
isThreadA = false;
isThreadB = true;
isThreadC = false;
abc.notifyAll();
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (abc) {
while(!isThreadB) {
try {
abc.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print("B");
isThreadA = false;
isThreadB = false;
isThreadC = true;
abc.notifyAll();
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (abc) {
while(!isThreadC) {
try {
abc.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print("C");
isThreadA = true;
isThreadB = false;
isThreadC = false;
abc.notifyAll();
}
}
}
}).start();
}
}
输出结果如下 :ABCABCABCABCABC
思路:解题思路大概是这样的,开启三个线程,每个线程一次打印一个字母,并且按照一定 的顺序打印,当打印A的时候,其他线程处于阻塞状态,打印完A以后,将线程解锁,让打印B的那个线程开启,其他线程处于阻塞状态,同理打印C的时候,阻塞 其他线程,这三个线程顺序循环,就达到顺序多次打印ABC的目的了。
这道题看似思路简单,其实主要需要用到wait()方法和notify()方法,还有关键字synchronized,只有充分理解了这些,才能解出这道题。下面我有必要讲解一下这两个方法,还有关键字synchronized。
在 JAVA中,是没有类似于PV操作、进程互斥等相关的方法的。JAVA的进程同步是通过synchronized()来实现的,需要说明的是,JAVA的 synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存锁的,在有线程获取该内存锁 后,其它线程无法访问该内存,从而实现JAVA中简单的同步、互斥操作。明白这个原理,就能理解为什么synchronized(this)与 synchronized(static XXX)的区别了,synchronized就是针对内存区块申请内存锁,this关键字代表类的一个对象,所以其内存锁是针对相同对象的互斥操作,而 static成员属于类专有,其内存空间为该类所有成员共有,这就导致synchronized()对static成员加锁,相当于对类加锁,也就是在该 类的所有成员间实现互斥,在同一时间只有一个线程可访问该类的实例。如果只是简单的想要实现在JAVA中的线程互斥,明白这些基本就已经够了。但如果需要 在线程间相互唤醒的话就需要借助Object.wait(), Object.nofity()了。
Obj.wait(),与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify是针对已经获取 了Obj锁进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内。从功 能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象 锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的 synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执 行。这样就提供了在线程间同步、唤醒的操作。Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要 的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。理解了这些解决这道面试题应该就不成问题了
相关推荐
java多线程每个线程挨着打印ABC的4种实现方式,有4个线程t1、t2、t3、t4,t1打印A后t2打印A再t3打印A再t4打印A,然后从新回到t1打印B再t2打印B...t4打印B... 4个线程轮流打印abc... 一个线程可以理解为一个人,打印...
### Java经典面试题知识点 #### Java数据结构容器 - **核心知识点**:Java集合框架,包括List、Set、Map等接口及其实现类。List接口代表有序的集合,例如ArrayList和LinkedList;Set接口代表不允许重复元素的集合,...
abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理abc ----VB家庭收支管理...
使用多线程和阻塞队列实现了ABC字母按顺序轮流打印
初始化块3. 变量4. 初始化块5. 构造器从这个例子可以看出,类的初始化顺序是非常关键的,特别是在...这些面试题涉及到Java语言的核心概念和常见问题,理解和掌握它们能够帮助你在面试中表现出色,解决实际编程问题。
- 方法重载(Overloading)指的是在一个类中可以有多个同名的方法,但是这些方法的参数列表必须不同(参数的数量、类型或顺序不同)。 - 选项A改变了方法的访问修饰符,这不影响是否构成重载。 - 选项B改变了返回值...
MATLAB中的abc-dq相坐标变换 MATLAB中的abc-dq相坐标变换是指在MATLAB软件中实现的坐标变换,从三相坐标系到两相旋转坐标系的变换。这种变换有两个步骤:首先,将三相坐标系变换到两相静止坐标系,然后将两相静止...
基于ABC-BP神经网络的年均含沙量预测研究 摘要:本文介绍了基于ABC-BP神经网络的年均含沙量预测模型,该模型结合人工蜂群算法优化了BP神经网络的权值和阈值,从而提高了模型的预测精度。该模型可以为河道治理和防洪...
Java多线程连续打印abc实现方法详解 Java多线程连续打印abc实现方法详解是 Java 编程...解决 Java 多线程连续打印abc问题需要使用同步机制来确保三个线程的顺序执行。可以使用两个锁或信号量来实现该问题的解决方案。
ABC-K-means.rar 是一个包含MATLAB实现的文件包,主要关注的是K-means聚类算法的一种改进版本,即结合了人工蜂群算法(Artificial Bee Colony, ABC)的优化策略。K-means聚类是一种广泛应用的数据分析方法,用于将...
标题中的“蜂群SVM(ABC-SVM)遗传算法SVM(GA-SVM)粒子群SVM(PSO-SVM)”是指利用生物进化算法优化支持向量机(Support Vector Machine, SVM)的一种方法。SVM是一种强大的监督学习模型,广泛应用于分类和回归...
"基于ABC-BP神经网络预测钢筋锈蚀程度.pdf" 通过对基于ABC-BP神经网络预测钢筋锈蚀程度的研究,我们可以了解到ABC-BP神经网络在钢筋锈蚀程度预测中的应用。该网络通过人工蜂群算法和BP神经网络原理相结合,设计出了...
标题中的"abc.rar_ABC_java多线程下载"表明这是一个关于Java多线程下载技术的压缩文件,其中"abc.rar"可能是文件的主名,而"ABC"可能是一种分类或者项目代号。描述中的"复件 Java多线程下载演示文件wdown.jar"暗示了...
Java作为一门广泛使用的编程语言,其面试题涵盖了众多的知识领域,包括基础语法、面向对象编程、集合框架、多线程、异常处理、JVM、IO流、网络编程、设计模式等。对于Java开发者来说,理解和掌握这些知识点是提升...
这些知识点不仅涵盖了基本概念,还涉及了一些进阶技巧,对于准备Java面试的人来说非常有用。 ### 1. Java 基本数据类型和输出 #### 示例题目: ```java int x = 010, y = 10, z = 0x10; System.out.println(x + "...
ABC-Linux-V.2.4.3-alpha.tar.gz 是一个针对Linux操作系统的压缩包文件,其版本号为2.4.3,标记为"alpha",意味着这是一个早期测试版,可能包含未解决的问题和功能不完善之处。这个软件主要用于BT(BitTorrent)下载...
### Java面试题解析 #### 1. 数据库连接池的工作机制 数据库连接池是一种用于管理数据库连接的技术。它预先创建多个数据库连接,并将其保存在一个池中。当应用程序需要访问数据库时,可以从池中获取一个已经建立好...
Java面向对象练习题经典 Java面向对象练习题是Java编程语言中非常重要的一部分,这些练习题涵盖了Java语言的基础知识,包括Java基本数据类型、运算符、控制结构、方法、类和对象、继承、多态、抽象类和接口等方面。...
### Java经典面试笔试题知识点解析 #### 一、判断题知识点解析 1. **创建类对象与回收对象** - **知识点**: 在Java中,创建一个新的类对象使用的关键字是`new`,而不是`free`。`new`操作符用于在内存中为对象分配...