概述
Thread和Object类的重要方法详解
方法概览
wait、notify、notifyAll
当一个线程调用了wait方法,则进入阻塞状态(blocked、waiting、timed_waiting),只有下面四种情况会被唤醒
- 另一个线程调用了这个对象的notify()方法且刚好被唤醒的是本线程
- 另一个线程调用这个对象的notifyAll()方法
- 过了wait(long timeout)规定的超时时间,如果传入0就是永久等待
- 线程自身调用了interrupt方法
notify 和notifyAll需要在synchronized关键字下运行
package com.hasson.ThreadObjectCommonMethods;
public class WaitAll implements Runnable {
private static final Object resourceA = new Object();
@Override
public void run() {
synchronized (resourceA) {
System.out.println(Thread.currentThread().getName() + "拿到了resourceA");
try {
System.out.println(Thread.currentThread().getName() + "要释放resourceA");
resourceA.wait();
System.out.println(Thread.currentThread().getName() + "释放resourceA了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Runnable r = new WaitAll();
Thread threadA = new Thread(r);
Thread threadB = new Thread(r);
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resourceA) {
resourceA.notify();
System.out.println(Thread.currentThread().getName() + "使用了notifyAll()");
}
}
});
threadA.start();
threadB.start();
Thread.sleep(1000);
threadC.start();
}
}
//Thread-0拿到了resourceA
//Thread-0要释放resourceA
//Thread-1拿到了resourceA
//Thread-1要释放resourceA
//Thread-2使用了notifyAll()
//Thread-0释放resourceA了
使用synchronized、wait、notify实现一个生产者消费者
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
public class ProducerConsumerMonitor {
public static void main(String[] args) {
EventStorage storage = new EventStorage();
Thread producer = new Thread(new Producer(storage));
Thread consumer = new Thread(new Consumer(storage));
producer.start();
consumer.start();
}
}
class EventStorage {
private int maxSize;
private List<Date> storage;
public EventStorage() {
maxSize = 10;
storage = new LinkedList<>();
}
public synchronized void put() {
while (storage.size() == maxSize) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.add(new Date());
System.out.println("仓库里有了" + storage.size() + "个产品");
notify();
}
public synchronized void take() {
while (storage.size() == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "拿到了" + storage.remove(0) + ",");
notify();
System.out.println("仓库里还有" + storage.size() + "个产品");
}
}
class Consumer implements Runnable {
private EventStorage storage;
public Consumer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
storage.take();
}
}
}
class Producer implements Runnable {
private EventStorage storage;
public Producer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
storage.put();
}
}
}
两个进程交替打印0-100
public class OddEvenSyn {
private static int count;
private static Object lock = new Object();
public static void main(String[] args) {
Integer index = new Integer(0);
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while (count < 50) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "尝试进来了");
if (count % 2 == 0) {
System.out.println(Thread.currentThread().getName() + "打印了" + count);
count++;
}
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (count < 50) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "尝试进来了");
if (count % 2 == 1) {
System.out.println(Thread.currentThread().getName() + "打印了" + count);
count++;
}
}
}
}
});
thread1.start();
thread2.start();
}
}
synchronized的方法比较低效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLTXxupn-1610348438210)(pics/7/image-20201211210510444.png)]
某个线程容易多次获得锁,所以应该使用wait和notify
- 拿到锁就立即打印
- 打印完,唤醒其他线程,就休眠
这里要注意的是 要用lock.wait(),不然就是默认是用自己的。
public class OddEvenWaitNotify {
private static int count = 0;
private static Object lock = new Object();
static class Runner implements Runnable {
@Override
public void run() {
while (count <= 100) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "打印了" + count);
count++;
lock.notify();
if (count <= 100)
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new Runner());
Thread thread2 = new Thread(new Runner());
thread1.start();
thread2.start();
}
}
sleep
sleep不释放锁(synchronized,lock),和wait不同
TimeUnit.SECONDS.sleep(1);
不同
join
作用:
因为新的线程加入了我们,所以我们要等到他执行完再出发
用法:
main等待thread1执行完毕,注意谁等谁。join(0)和wait(0)都是指无限时间,直到被唤醒
原理:
Thread类实现完之后会使用一个notify的原生代码(c++第层),join实际上就是调用了一个wait(0)方法
等价的
- 在join期间,线程处于waiting状态
yield
作用:
释放我的CPU时间片
定位:
JVM不保证遵循,一般不使用
yield和sleep区别:是否随时可能再次被唤醒
最后
以上就是狂野大雁为你收集整理的Thread和Object类的重要方法Thread和Object类的重要方法详解的全部内容,希望文章能够帮你解决Thread和Object类的重要方法Thread和Object类的重要方法详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复