1.
sleep-wait-yield区别
sleep是Thread类中的一个静态方法,其定义如下,
public static void sleep(long millis)throws InterruptedException
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响,如果指定睡眠的时间到达,则从阻塞状态转变成就绪状态,等待运行。
yield只是使当前线程重新回到可执行状态,让其它同一优先级的线程先运行,所以执行yield()的线程有可能进入到可执行状态后马上又被执行。
wait是Object类中定义的方法,与notify/notifyAll()在一起成对使用,提供线程间的等待-通知机制。
wait是Object类的方法,其定义如下,
public final void wait()throws InterruptedException//相当于wait(0)
public final void wait(long timeout)throws InterruptedException
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
调用wait()/notify()时,都必须首先获得相关的锁.而wait()被调用后,会释放之前进行同步块所获取到的锁。
synchronized(obj){
//wait(), notify(), notifyAll()
}
2.
wait-notify等待通知机制
wait/notify提供了一种通知机制,wait/notify关键字适用于一个线程通知另一个线程所需的条件状态已就绪,最常用于线程在循环中休眠直到获取特定条件的场景。
synchronized(lock){
//flag初始为false,是为了避免在执行wait()以前,notify()就已经执行了。
while(!flag){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//具体的业务逻辑在这里
obj.doSomething();
}
synchronized(lock){
flag = true;
lock.notify();
}
为什么要使用flag?
因为完全有可能notify()在wait()前被调用,这时wait()就会无限的等待下去,而没有任何通知。而加上flag,无论notify(),wait()谁先执行,都不会对最终结果造成任何的影响。假如,notify()先调用,那么wait所在的while-block将不会被执行,直接执行业务逻辑相关代码;如果wait()先执行,所在线程将阻塞,而此时notify()给出通知,wait()线程重新执行,并退出while-block,执行业务逻辑代码。
测试代码:
两个线程共享的locker和标识flag放在一个全局变量类中
class GlobalVar{
public final static Object locker = new Object();
public static boolean flag = false;
}
Waiter类
class Waiter extends Thread{
public void run(){
while(true){
synchronized(GlobalVar.locker){
while(!GlobalVar.flag){
try {
GlobalVar.locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
GlobalVar.flag = false;
}//synchronized end
//do something here
System.out.println("Waiter:完成一个新分配的任务");
}
}
}
Noticer类
class Noticer extends Thread{
public void run(){
synchronized(GlobalVar.locker){
GlobalVar.flag = true;
GlobalVar.locker.notify();
System.out.println("Noticer:分配一个新任务通知");
}
}
}
Main函数所在类
public class Test2 {
public static void main(String[] args) {
Noticer n = new Noticer();
Waiter w = new Waiter();
n.start();
w.start();
}
}
测试输出:
Noticer:分配一个新任务通知
Waiter:完成一个新分配的任务
使用wait-notify需要注意:
(1).调用
notify是随机的唤醒某一thread.而notifyAll则是唤醒所有等待的线程, 但只有一个线程可以在唤醒后lock object monitor,所以, notifyAll操作也是有利弊的.
(2).
wait、notify、notifyAll必须在synchronized修饰的代码块中执行,否则会在运行的时候抛出IllegalMonitorStateException异常
(3).在循环语句wait的时候一定要设定循环的条件--这样能够避免wait开始之前,线程所需的条件已经被其他线程提供了却依然开始此线程wait导致的时间消耗。同时,这种办法还能够保证你的代码不被虚假的信息唤醒。
(4).总是要保证在调用notify和notifyAll之前,能够提供符合线程退出等待的条件。否则会出现即使线程接收到通知信息,却不能退出循环等待的情况。
3.
join()方法
join方法是使当前线程阻塞,直到所引用的线程结束才激活.
public final void join()throws InterruptedException
4.
synchronized关键字
synchronized有四种使用方式:
synchronized method(){}
synchronized (obj)
static synchronized method(){}
synchronized(classname.class)
前面两个使用的锁是对象monitor,后面两者使用的是类monitor,都可以实现互斥访问。
一个对象只有一个对象monitor,一个类也只有一个类monitor。静态方法使用类monitor进行同步,而普通方法则使用对象monitor进行同步。
分享到:
相关推荐
一个线程调用`wait()`会释放锁并等待,而`notify()`或`notifyAll()`唤醒等待的线程。 - 使用这三个方法时需格外小心,避免死锁和活锁的情况。 5. **线程池**: - `ExecutorService`和`ThreadPoolExecutor`提供了...
在Java多线程编程中,wait和notify是两个非常重要的方法,它们都是Object类的方法,用于线程之间的通信和同步。下面我们将详细解释wait和notify的用法。 wait方法 wait方法是Object类的一个方法,用于让当前线程...
在Java中,`wait()` 和 `notify()` 方法是实现线程间通信和协作的重要工具,它们属于 `java.lang.Object` 类,这意味着所有类都默认继承了这两个方法。本文将详细探讨如何使用 `wait()` 和 `notify()` 来控制子线程...
public class ThreadWaitNotify { public static void main(String[] args) throws InterruptedException { DemoTest demoTest = new DemoTest(); // 使用线程池异步执行waitTest方法 ExecutorService ...
本文旨在解析一个具体的Java多线程示例代码,以帮助读者更好地理解`wait()`与`notify()`方法的作用及其实现机制。这两个方法是Java中实现线程间通信的重要手段之一,尤其在解决生产者消费者模型、读者写者问题等经典...
Java线程编程涉及到线程同步、线程安全、死锁等问题,例如可以使用synchronized关键字、wait()、notify()和notifyAll()方法来协调线程间的协作。此外,Java还提供了一些高级并发工具,如Semaphore(信号量)、...
- `wait()`, `notify()`, `notifyAll()`:基于对象监视器的线程通信,用于线程间的协作。 - `BlockingQueue`:一种高级的线程间通信方式,如`ArrayBlockingQueue`、`LinkedBlockingQueue`等。 5. **线程池**: -...
wait()让当前线程等待,notify()唤醒一个等待的线程,notifyAll()唤醒所有等待的线程。它们通常与synchronized结合使用。 7. Executors框架 Java 5引入了ExecutorService和Future接口,提供了一种更灵活的线程池...
当一个线程调用`wait()`,它会释放对象锁并进入等待状态,直到其他线程调用同一对象的`notify()`或`notifyAll()`来唤醒它。注意,这些方法必须在同步块或同步方法中使用,以防止死锁。 3. `join()`:让当前线程等待...
它允许一个线程等待特定条件发生(通过调用`wait()`方法),并在条件满足时由其他线程唤醒(通过调用`notify()`或`notifyAll()`方法)。 - **`wait()`**:使当前线程进入等待状态,直到被其他线程唤醒或等待超时。 ...
- `wait()`使当前线程进入等待状态,`notify()`唤醒一个等待线程。 - **题2**:如何使用`wait()`和`notify()`方法实现生产者消费者模型? - 生产者在向缓冲区添加元素后调用`notify()`,消费者在取元素前调用`...
本文将深入探讨`wait()`, `notify()`以及它们与`sleep()`方法的区别,这些都是Java中与线程同步密切相关的概念。 首先,`wait()`, `notify()`和`notifyAll()`是Object类中的方法,它们主要用于线程间通信和协作。...
- **同步**:确保多线程间的操作顺序和一致性,`synchronized`块/方法、`wait()`, `notify()`, `notifyAll()`等机制用于线程间同步。 5. **线程的通信** - **生产者消费者模型**:使用`BlockingQueue`进行线程间...
此外,Java中的wait/notify机制也与线程状态有关。当线程调用某个对象的wait方法时,它会从RUNNABLE状态变为OBJECT_WAIT状态,并释放掉该对象上的锁。此时线程等待在ObjectMonitor上,直到其他线程调用了同一个对象...
Java提供了多种同步机制,如`synchronized`关键字、`wait()`/`notify()`、`Lock`接口(如`ReentrantLock`)、`Semaphore`信号量等。 理解并熟练运用这些知识点对于编写高并发的Java应用程序至关重要。注意,多线程...
- 守护(Timed Waiting):线程调用了带有超时参数的`wait()`、`sleep()`或`join()`,等待一段时间后自动唤醒。 - 结束(Terminated):`run()`方法执行完毕,线程结束。 3. **线程同步** - `synchronized`...
- 线程同步机制:如`synchronized`关键字、`wait()`, `notify()`, `notifyAll()`方法以及`Lock`接口。 - 线程池的使用:如`ExecutorService`和`ThreadPoolExecutor`,以及如何优化线程池配置。 - 异常处理:线程...
Java提供了多种机制来实现线程间的通信,包括使用wait(), notify()和notifyAll()方法,以及使用synchronized关键字控制并发访问共享资源。这些方法都定义在java.lang.Thread类中。 1. **wait(), notify()和...
- `Object.wait()`: 使当前线程等待,直到另一个线程调用此对象上的`notify()`或`notifyAll()`方法,或等待时间超时。 - `Object.notify()`: 唤醒在此对象监视器上等待的单个线程。 - `Object.notifyAll()`: 唤醒...
在学习Java线程时,还应掌握同步机制,包括`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法,以及`ReentrantLock`、`Semaphore`、`CyclicBarrier`等高级并发工具。理解这些工具的用法和限制,可以...