您的位置:首页 > 移动开发 > Objective-C

Object中的wait,notify,notifyAll基本使用

2018-03-21 20:27 441 查看
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同时,释放了对象锁的控制。object.wait()方法:让拥有object对象的锁的线程进入等待状态,并释放对象锁。object.wait()和object.notify()和object.notifyall()必须写在synchronized方法内部或者synchronized块内部,因为: 这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁。(1)wait() 方法用来控制当前线程停止执行,等待其他线程对此Object实例调用notify或者notifyAll方法之后再继续执行 
(2)wait(long timeout) 此方法的作用和wait()类似,但是增加了一个超时的设置,如果等待时间超过了timeout设定的毫秒数,那么当前线程会继续执行 
(3)notify()方法从所有wait线程中选择一个线程,让它开始执行 
(4)notifyAll()方法通知所有等待此对象的线程,开始执行1、假定我们有两个线程要打印1到9这9个数字,要求第一个线程打印1,2,3然后停止打印,由线程2打印4,5,6,然后线程2停止打印,通知线程1继续打印7,8,9.
public class Example {
public static void main(String[] args) {
Object printACon = new Object();
Object printBCon = new Object();
new Thread(new PrintA(printACon, printBCon)).start();
new Thread(new PrintB(printACon, printBCon)).start();
}
}

class PrintA implements Runnable {
private Object objectA = null;
private Object objectB = null;

PrintA(Object printACon, Object printBCon) {
objectA = printACon;
objectB = printBCon;
}
@Override
public void run() {
System.out.println("PrintA start......");
for (int i = 1; i < 4; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("printA print " + i);
}

try {
// A线程打印完了1、2、3后通知线程开始打印并且自身开始等待
synchronized(objectA) {
synchronized(objectB) {
objectB.notify();
}
objectA.wait();
}

} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("PrintA reStart......");
for (int i = 7; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("printA print " + i);
}
}

}

class PrintB implements Runnable {
private Object objectA = null;
private Object objectB = null;

PrintB(Object printACon, Object printBCon) {
objectA = printACon;
objectB = printBCon;
}

@Override
public void run() {
try {
// 刚开始B线程等待A线程打印完1、2、3
synchronized(objectB) {
objectB.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("PrintB start......");
for (int i = 4; i < 7; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("printB print " + i);
}

// B线程打印完了4、5、6后就通知A线程继续打印
synchronized(objectA) {
objectA.notify();
}
}
}
2、生产者-消费者问题
class Producer implements Runnable
{
private final List<Integer> taskQueue;
private final int           MAX_CAPACITY;

public Producer(List<Integer> sharedQueue, int size)
{
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}

@Override
public void run()
{
int counter = 0;
while (true)
{
try
{
produce(counter++);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}

private void produce(int i) throws InterruptedException
{
synchronized (taskQueue)
{
while (taskQueue.size() == MAX_CAPACITY)
{
System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
taskQueue.wait();
}

Thread.sleep(1000);
taskQueue.add(i);
System.out.println("Produced: " + i);
taskQueue.notifyAll();
}
}
}
class Consumer implements Runnable
{
private final List<Integer> taskQueue;

public Consumer(List<Integer> sharedQueue)
{
this.taskQueue = sharedQueue;
}

@Override
public void run()
{
while (true)
{
try
{
consume();
} catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}

private void consume() throws InterruptedException
{
synchronized (taskQueue)
{
while (taskQueue.isEmpty())
{
System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
int i = (Integer) taskQueue.remove(0);
System.out.println("Consumed: " + i);
taskQueue.notifyAll();
}
}
}
public class ProducerConsumerExampleWithWaitAndNotify
{
public static void main(String[] args)
{
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 5;
Thread tProducer = new Thread(new Producer(taskQueue, MAX_CAPACITY), "Producer");
Thread tConsumer = new Thread(new Consumer(taskQueue), "Consumer");
tProducer.start();
tConsumer.start();
}
}

Output:

Produced: 0
Consumed: 0
Queue is empty Consumer is waiting , size: 0
Produced: 1
Produced: 2
Consumed: 1
Consumed: 2
Queue is empty Consumer is waiting , size: 0
Produced: 3
Produced: 4
Consumed: 3
Produced: 5
Consumed: 4
Produced: 6
Consumed: 5
Consumed: 6
Queue is empty Consumer is waiting , size: 0
Produced: 7
Consumed: 7
Queue is empty Consumer is waiting , size: 0
原文地址:http://blog.csdn.net/hp910315/article/details/50148683
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java锁