程序会启动20个线程,20个线程都使用同一个sync的object(名字为SYNC)。 线程启动代码如下:
final TC[] ts = new TC[20];
for (int i = 0; i < ts.length; i++) {
TC target = new TC("TC " + i, SYNC1);
Thread thread = new Thread(target);
ts[i] = target;
thread.start();
}
------------------------------------------------------------
接下来马上启动另外一个线程用于做notify操作。
// 一个用于停止的Thread
new Thread(new Runnable() {
public void run() {
synchronized (SYNC1) {
int i = 10;
while (i > 0) {
System.out.println("Now will notify the thread " + i);
ts[i].notifySelf();
try {
SYNC1.wait(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i--;
}
}
}
}).start();
------------------------------------------------------------
启动的TC线程代码如下:
class TC implements Runnable {
private final String name;
private final Object sync;
private boolean isRunning = false;
public TC(String name, Object sync) {
this.name = name;
this.sync = sync;
}
public void run() {
synchronized (sync) {
while (true) {
// 每个线程默认都加入线程池排队。这样有助于打乱线程在主线程中启动的顺序,方便后面的观测。
if (!isRunning) {
try {
sync.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isRunning = true;
}
System.out.println(name + " Running .......");
try {
sync.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}// Wait 1 second
}
}
}
public void notifySelf() {
synchronized (sync) {
System.out.println("Coming to notify the thread " + name);
sync.notify();
}
}
}
---------------------------分割线---------------------------------
输出日志如下(//部分是我加的注释,不是实际输出):
Now will notify the thread 10 //首先试着notify第10个TC
Coming to notify the thread TC 10 // 也确实调用了SYNC的notify操作,但是因为当前还没有任何线程在wait,所以这个notify信号就被丢弃掉了。这个notify过去就过去了。不会影响后面的任何操作了。
TC 1 Running .......
TC 5 Running .......
TC 0 Running .......
TC 2 Running .......
TC 4 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 13 Running .......
TC 15 Running .......
TC 17 Running .......
TC 3 Running .......
TC 18 Running .......
TC 16 Running .......
TC 19 Running ....... //启动20线程,这20个线程启动的顺序已经被打乱了。不会从头到尾1-20的启动,而是如log显示1,5,0,2,4,6,8,10,12,14.........
//每个线程启动后会被wait(). wait的顺序是1,5,0,2,4,6,8,10,12,14.........
Now will notify the thread 9
Coming to notify the thread TC 9
TC 1 Running .......
Now will notify the thread 8
Coming to notify the thread TC 8
TC 5 Running .......
Now will notify the thread 7
Coming to notify the thread TC 7
TC 0 Running .......
Now will notify the thread 6
Coming to notify the thread TC 6
TC 2 Running .......
Now will notify the thread 5
Coming to notify the thread TC 5
TC 4 Running .......
Now will notify the thread 4
Coming to notify the thread TC 4
TC 6 Running .......
Now will notify the thread 3
Coming to notify the thread TC 3
TC 8 Running .......
Now will notify the thread 2
Coming to notify the thread TC 2
TC 10 Running .......
Now will notify the thread 1
Coming to notify the thread TC 1
TC 12 Running .......
//总共10个notify操作,但是因为启动的时候一个notify因为没有任何wait的线程给丢弃了,所以,这里只有9个notify起到了作用。他们是按照进入pool的顺序排队给notify。
//一个notify操作仅仅激活一个wait队列中的第一个线程。一对一操作。
-------------------------------分割线------------------------------
使用notifyAll代替notify。
日志输出:
Now will notify the thread 10
Coming to notify the thread TC 10 //第一个notifyAll的操作还是被丢弃了
TC 0 Running .......
TC 1 Running .......
TC 3 Running .......
TC 5 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 13 Running .......
TC 15 Running .......
TC 17 Running .......
TC 19 Running .......
TC 2 Running .......
TC 4 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 16 Running .......
TC 18 Running .......
Now will notify the thread 9
Coming to notify the thread TC 9 //一个notifyAll的操作notify所以正在wait的线程。
TC 0 Running .......
TC 1 Running .......
TC 3 Running .......
TC 5 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 2 Running .......
TC 13 Running .......
TC 15 Running .......
TC 4 Running .......
TC 17 Running .......
TC 19 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 16 Running .......
TC 18 Running .......
分享到:
相关推荐
在Java中,notifyAll()方法是Object类中的方法,用于唤醒所有等待对象的线程,而不是像notify()方法那样只唤醒一个线程。 在Java线程中,notifyAll()方法经常被用来唤醒所有等待对象的线程,以便它们可以继续执行。...
- 线程同步:synchronized关键字,wait(), notify(), notifyAll()方法,以及Lock接口的使用。 - 守护线程与线程池:理解守护线程的概念,以及ExecutorService线程池的创建与管理。 8. **反射机制** - 类的加载:...
在Java中,`wait()`, `notify()`, `notifyAll()`方法是`Object`类的成员,而不是`Thread`类的,这意味着任何对象都可以作为等待和通知的基础。 **1. 状态变量(State Variable)** 状态变量是线程间通信的关键。当...
综上所述,这个“线程学习小Test”通过几个具体的Java源代码文件,深入浅出地展示了Java中线程同步的重要方法及其应用。通过学习和实践这些示例,开发者能够更好地理解和掌握多线程环境下的线程同步策略,提升并发...
`wait()`、`notify()`和`notifyAll()`是Java `Object`类的三个方法,它们用于线程间的通信。这些方法必须在同步环境中(即synchronized方法或synchronized代码块)使用,否则会抛出`IllegalMonitorStateException`...
5. **多线程**:掌握线程的创建(通过Thread类或实现Runnable接口),同步机制(synchronized,wait(),notify(),notifyAll()),线程池(ExecutorService)以及并发工具类(如Semaphore,CyclicBarrier,...
5. **多线程**:Java提供了丰富的API来支持多线程编程,如Thread类、Runnable接口、synchronized关键字、wait()、notify()和notifyAll()方法等。 6. **输入/输出流**:包括文件I/O、字节流和字符流、缓冲流、对象...
单元测试与主函数(1:Unit test and main function-Java API 实战.md) 单元测试是软件开发过程中的重要环节,它能确保代码的正确性。笔记中详细介绍了JUnit框架的使用,以及如何编写和执行单元测试。同时,主函数...
7. **多线程**:理解线程的概念,创建线程的方式(Thread类和Runnable接口),同步机制(synchronized关键字,wait()、notify()和notifyAll()方法),以及线程池的使用。 8. **反射API**:通过反射可以在运行时获取...
Java提供了多种工具来实现这一点,如`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法,以及`java.util.concurrent`包下的高级并发工具。 假设我们有一个`ThreadA`和`ThreadB`,它们都需要检查对方...
例如,线程2在完成其任务后,调用了`notify()`方法("Sleep sometime after notify to test if others can end first"),然后退出同步块("Name:2 willExit the synchronize block"和"Name:2 End.false")。...
线程间的同步和通信可以借助synchronized关键字、wait()、notify()和notifyAll()方法。 9. **泛型**:泛型是Java 5引入的新特性,用于增强类型安全,减少类型转换的麻烦。泛型可以应用于类、接口和方法,限制可存储...
学习如何创建和管理线程,同步机制(如synchronized关键字、Lock接口),以及线程间的通信(wait、notify、notifyAll)等,是提升程序并发性能的重要手段。 6. **I/O流**:Java的I/O流系统分为字节流和字符流,包括...
这部分可能包括线程的创建、同步、通信(如使用synchronized关键字、wait()、notify()和notifyAll()方法)以及线程池的使用(如ExecutorService)。 61. 异常处理:Java异常处理通过try-catch-finally语句块进行,...
在Java中,线程的阻塞与唤醒主要通过Object类中的wait()、notify()和notifyAll()方法实现。wait()方法会使当前线程释放对象锁并进入等待状态,直到其他线程调用相同对象的notify()或notifyAll()方法。notify()方法则...
- 同步可以通过`synchronized`关键字,`wait()`, `notify()`和`notifyAll()`来实现。`wait()`让当前持有锁的线程等待,释放锁;`sleep()`使线程暂停一段时间,不会释放锁;`notify()`唤醒一个等待的线程,但不保证...
- 线程同步:了解synchronized关键字,wait(), notify()和notifyAll()方法,以及死锁问题。 9. **反射** - Class类:使用Class对象获取类的信息,如类名、构造器、方法等。 - 动态创建对象:通过Class的new...
- 调用`wait()`后,线程必须等待另一个线程调用`notify()`或`notifyAll()`来重新获得锁。 - 在调用`wait()`之前,必须先获得锁;同样,在调用`notify()`或`notifyAll()`时,也必须持有锁。 ### 二、Java文件I/O操作...
Java提供了wait()、notify()和notifyAll()方法来进行线程间的通信,这些方法必须在同步块或同步方法中使用,以避免死锁和其他并发问题。 通过以上内容,我们可以了解Java多线程的基本概念和操作,但在实际应用中,...
Java提供了多种线程同步机制,如`synchronized`关键字、`wait()`, `notify()`和`notifyAll()`方法、`ReentrantLock`以及`Semaphore`等。在购票系统中,可能使用了`synchronized`关键字对购票方法进行同步,确保同一...