您的位置:首页 > 大数据 > 人工智能

Thread线程间通讯-wait,notify

2014-03-10 22:33 501 查看
解释:

When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time.

The process by which this synchronization is achieved is called threadsynchronization.

The synchronized keyword in Java creates a block of code referred to as a critical section. Every Java object with a critical section of code gets a lock associated with the object. To enter a critical section, a thread needs to obtain the corresponding object'slock.

This is the general form of the synchronized statement:
synchronized(object) {
// statements to be synchronized
}


Here, object is a reference to the object being synchronized. A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object's monitor.

/**

* 线程间通讯:

* 其实就是多个线程在操作同一个资源

* 但是操作的动作不同

*/

wait, notify, notifyAll()

都是用在同步中,因为要对持有监视器(锁)的线程操作。

所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法,要定义在object类中呢?

因为这些方法在操作同步中线程时,都必须要标识他们所操作线程持有的锁,

只有同一个锁上得被等待线程,可以被统一个锁上得notify唤醒。

不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以可以被任意对象调用的方法(wait, notify,notifyAll)定义在object类中

举例:Input类用于,传入内容,Output类用于传出内容,由于传输的数据是共享的,所以将这个传输的数据对象作为“锁”。

等待====》唤醒

为了能够输入线程,和输出线程一次只运行一个线程,于是:输入线程工作,输出等待,输入线程等待,输出线程工作。

由于此例中进加入了两个线程,所以使用notify来唤醒wait状态下的线程。

notify 只唤醒在线程池中最上面的那个线程

notify 唤醒线程池中所有的线程

public class Input implements Runnable {

private Res r;

public Input(Res r) {
super();
this.r = r;
}

@Override
public void run() {
int x = 0;
while (true) {
synchronized (r) {
if (r.flag)
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (x == 0) {
r.name = "LI";
r.sex = "femal";
} else {
r.name = "李雷";
r.sex = "男";
}
x = (x + 1) % 2;
r.flag = true;
r.notify();
}
}
}

}


public class Output implements Runnable {

private Res r;

public Output(Res r) {
super();
this.r = r;
}

@Override
public void run() {
while (true) {
synchronized (r) {
if (!r.flag)
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(r.name + "," + r.sex);
r.flag = false;
r.notify();
}
}
}

}


public class Res {

String name;
String sex;
boolean flag = false;

}


public class InputOutputDemo {
public static void main(String[] args) {
Res r = new Res();

Input in = new Input(r);
Output out = new Output(r);

Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}
}


由于共享对象是Res,可以将同步内容都放在Res中:
public class Res {

private String name;
private String sex;
private boolean flag = false;

public synchronized void set(String name, String sex) {

if (flag)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

this.name = name;
this.sex = sex;

flag = true;
this.notify();
}

public synchronized void out() {

if (!flag)
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "..." + sex);

flag = false;
this.notify();
}

}


public class Input implements Runnable {

private Res r;

public Input(Res r) {
super();
this.r = r;
}

@Override
public void run() {
int x = 0;
while (true) {

if (x == 0)
r.set("Li", "female");
else
r.set("李雷", "男");

x = (x + 1) % 2;
}
}
}


public class Output implements Runnable {

private Res r;

public Output(Res r) {
super();
this.r = r;
}

@Override
public void run() {
while (true) {
r.out();
}
}

}


public class InputOutputDemo {
public static void main(String[] args) {
Res r = new Res();

new Thread(new Input(r)).start();
new Thread(new Output(r)).start();

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: