我的问题:三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC。
我编写的代码:
package 并发编程.work2;
public class Test {
private static volatile String CURRENT_THREAD = "A";
public static void main(String[] args) {
Thread t1 = new Thread(new PrintThreadName(), "A");
Thread t2 = new Thread(new PrintThreadName(), "B");
Thread t3 = new Thread(new PrintThreadName(), "C");
t1.start();
t2.start();
t3.start();
}
static class PrintThreadName implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
synchronized (CURRENT_THREAD) {
// 从A开始
while (!CURRENT_THREAD.equals(Thread.currentThread().getName())) {
try {
CURRENT_THREAD.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(CURRENT_THREAD);
// 线程打印完毕后,设置下一个要打印的线程标识,并唤醒其他线程
if (CURRENT_THREAD.equals("A")) {
CURRENT_THREAD = "B";
} else if (CURRENT_THREAD.equals("B")) {
CURRENT_THREAD = "C";
} else if (CURRENT_THREAD.equals("C")) {
CURRENT_THREAD = "A";
}
CURRENT_THREAD.notifyAll();
}
}
}
}
}
但是出现了错误
哪个地方出现了问题呢?
package 并发编程.work2;
public class Test {
private static final Object lock = new Object();
private static volatile String CURRENT_THREAD = "A";
public static void main(String[] args) {
Thread t1 = new Thread(new PrintThreadName(), "A");
Thread t2 = new Thread(new PrintThreadName(), "B");
Thread t3 = new Thread(new PrintThreadName(), "C");
t1.start();
t2.start();
t3.start();
}
static class PrintThreadName implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
synchronized (lock) {
// 从A开始
while (!CURRENT_THREAD.equals(Thread.currentThread().getName())) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(CURRENT_THREAD);
// 线程打印完毕后,设置下一个要打印的线程标识,并唤醒其他线程
if (CURRENT_THREAD.equals("A")) {
CURRENT_THREAD = "B";
} else if (CURRENT_THREAD.equals("B")) {
CURRENT_THREAD = "C";
} else if (CURRENT_THREAD.equals("C")) {
CURRENT_THREAD = "A";
}
lock.notifyAll();
}
}
}
}
}
主要的问题是:
// 线程打印完毕后,设置下一个要打印的线程标识,并唤醒其他线程
if (CURRENT_THREAD.equals("A")) {
CURRENT_THREAD = "B";
} else if (CURRENT_THREAD.equals("B")) {
CURRENT_THREAD = "C";
} else if (CURRENT_THREAD.equals("C")) {
CURRENT_THREAD = "A";
}
你使用一个volatile修饰的字符串CURRENT_THREAD来充当锁的角色
但是却在锁对象释放自己拥有的锁之前就把锁的引用给修改了
也就会出现 现在的锁对象其实已经被修改了(它是没有锁的 锁在之前的对象身上)
你还要让它释放锁 属于是强人所难了 所以会报错
这个错误产生的原因是某一线程在等待其他线程释放锁 但是突然要求它释放锁 它还在等呢怎么会有锁 所以就会抛出IllegalMonitorStateException
解决方法就是额外使用另一个锁对象来实现同步 不要在锁对象释放锁之前对它进行任何修改 可以参照楼上的方案
问题内容: 我需要使线程顺序。他们需要按以下顺序启动: 当D完成时,C可以完成,然后B,然后是A。 在这种情况下,最好使用线程或?为什么呢? 我的线程需要启动并打印消息,完成后需要打印。 问题答案: 由于您正在等待“其他”线程完成(即完成执行),因此是更好的选择。 的javadoc 简单地说: 等待该线程死亡。 然后,该机制相对简单: 要说明:您需要参考。因此,指向,指向,指向和不指向任何对象(它
本文向大家介绍Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll),包括了Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)的使用技巧和注意事项,需要的朋友参考一下 本篇我们来研究一下 wait() notify() notifyAll() 。 DEMO1: wait() 与 notify() DEMO1 输出: 注意: 使用 wait
问题内容: 根据Java线程状态信息,调用wait()将导致线程进入BLOCKED状态。但是,这段代码将导致(在调用之后)处于等待状态的线程。 我有什么问题吗?有人可以向我解释这种行为吗?任何帮助,将不胜感激! 问题答案: 线程在等待通知。然后,它变为BLOCKED,试图重新进入同步区域,直到所有其他线程都离开。 您发布的链接中的有关部分(关于WAITING): 例如,在某个对象上调用Object
从逻辑上讲,调用< code>wait方法的线程应该已经获得了正在调用< code>wait的对象的固有锁。 oracle教程中提到“在对象的同步方法中调用< code>wait是获取内部锁的一种简单方法”,这意味着至少还有另一种方法可以获取锁。 我的问题是,为了调用< code>wait,除了在synchronized方法内部调用< code>wait之外,还有其他方法可以获取内部锁吗?...它
本文向大家介绍Java多线程——之一创建线程的四种方法,包括了Java多线程——之一创建线程的四种方法的使用技巧和注意事项,需要的朋友参考一下 1.实现Runnable接口,重载run(),无返回值 2.继承Thread类,复写run() 使用时通过调用Thread的start()(该方法是native),再调用创建线程的run(),不同线程的run方法里面的代码交替执行。 不足:由于java为单
主要内容:1 什么是Java join()方法,2 Java join()方法语法,3 Java join()方法例子1,4 Java join()方法例子21 什么是Java join()方法 Java join() 方法表示等待线程死亡。换句话说,它导致当前正在运行的线程停止执行,直到与之连接的线程完成其任务为止。 2 Java join()方法语法 3 Java join()方法例子1 输出结果为: 如上例所示,当t1完成其任务时,t2和t3开始执行。 4 Java join()方法例子2