2012/8/7-多线程间的通讯::
多个线程在操作同一个资源,但是操作的方式不一样.
线程控制函数:都在Object类中.原因:控制函数用在同一个锁中,而锁可以为任意对象,故只能生命在Object中.
wait() 是当前线程处于等待状态.
notify() 唤醒线程池中最先等待的线程.
notifyAll() 唤醒线程池中的所有线程.
用于同步中(相同的锁).
wait与sleep的区别:
1、wait可以别的线程来唤醒,也可以在特定时间后被唤醒;而sleep只能在特定时间后被唤醒;
2、wait释放资源,释放锁;sleep释放资源,不释放锁;
例子中通过控制两个线程的wait和nitify操作,进行间隔输出.
class Res //定义一个资源
{
String name;
String sex;
Boolean b = false; //控制开关,初始值为false.
}
class Input implements Runnable //向资源中赋值
{
Res r;
Input(Res r)
{
this.r = r;
}
public void run()
{
int x = 0;
while (true)
{
synchronized(r) //之所以用r作为锁,是因为两个Runnable的子类对象,拥有共同的r资源对象,
//而无论是用this还是在单独在类中建立一个Object的锁,两个线程都不是同样的锁.
{
if (r.b)
try{r.wait();}catch(Exception e){} //wait方法抛出异常,而父类的run方法没有抛出异常,子类覆盖父类,
//只能抛出父类的异常或其子类异常,故这里只能处理异常,而无法抛出.
if (x == 0)
{
r.name = "mike";
r.sex = "male";
}
else
{
r.name = "lily";
r.sex = "female";
}
x = (x + 1)%2; //更改x的值.
r.b = true;
r.notify(); //针对当前的锁,进行唤醒操作.
}
}
}
}
class Output implements Runnable //从资源中取值
{
Res r;
Output(Res r)
{
this.r = r;
}
public void run()
{
while (true)
{
synchronized(r)
{
if (!r.b)
try{r.wait();}catch(Exception e){}
System.out.println(r.name + ".." + r.sex);
r.b = false;
r.notify();
}
}
}
}
class ThreadCommunicationDemo
{
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();
}
}
优化后的代码:
class Res //定义一个资源
{
private String name;
private String sex;
private Boolean b = false;
public synchronized void set(String name, String sex)
{
if (b)
try
{
wait();
}
catch (Exception e)
{
}
this.name = name;
this.sex = sex;
b = true;
notify();
}
public synchronized void printEx()
{
if (!b)
try
{
wait();
}
catch (Exception e)
{
}
System.out.println(name + ".." + sex);
b = false;
notify();
}
}
class Input implements Runnable //向资源中赋值
{
Res r;
Input(Res r)
{
this.r = r;
}
public void run()
{
int x = 0;
while (true)
{
if (x == 0)
{
r.set("mike", "male");
}
else
{
r.set("lily", "female");
}
x = (x + 1)%2; //更改x的值.
}
}
}
class Output implements Runnable //从资源中取值
{
Res r;
Output(Res r)
{
this.r = r;
}
public void run()
{
while (true)
{
r.printEx();
}
}
}
class ThreadCommunicationDemo2
{
public static void main(String[] args)
{
Res r = new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}
}