帮忙看一段程序,关于线程的
//Sender.java
class Buffer
{
private int value;
private boolean isEmpty=true;
synchronized void put(int i)
{
while(!isEmpty)
{
try
{
this.wait();
}
catch(InterruptedException e)
{
System.out.println(e.getMessage());
}
}
value=i;
isEmpty=false;
notify();
}
synchronized int get()
{
while(isEmpty)
{
try
{
this.wait();
}
catch(InterruptedException e)
{
System.out.println(e.getMessage());
}
}
isEmpty=true;
notify();
return value;
}
}
class Sender extends Thread
{
private Buffer bf;
public Sender(Buffer bf)
{
this.bf=bf;
}
public void run()
{
for(int i=1;i <6;i++)
{
bf.put(i);
System.out.println( "Sender put "+i);
}
}
public static void main(String args[])
{
Buffer bbb=new Buffer();
(new Sender(bbb)).start();
(new Receiver(bbb)).start();
}
}
class Receiver extends Thread
{
private Buffer bf;
public Receiver(Buffer bf)
{
this.bf=bf;
}
public void run()
{
for(int i=1;i <6;i++)
System.out.println( "\t\t Receiver get: "+bf.get());
}
}
这是书上的例子程序,结果出来是
Sender put1
Sender put2
Receiver get:1
Sender put3
Receiver get:2
Sender put4
Receiver get:3
Sender put5
Receiver get:4
Receiver get:5
我这里想请教的是,为什么不是写一条读一条的
还有,为什么写了2条后,读出来的数据却还是1呢?
请教啦
[解决办法]
class Buffer {
private int value;
private boolean isEmpty=true;
synchronized void put(int i) {
while(!isEmpty) {
try {
this.wait();
} catch(InterruptedException e) {
System.out.println(e.getMessage());
}
}
value=i;
System.out.println( "putting "+i);
isEmpty=false;
this.notify();
}
synchronized int get() {
while(isEmpty) {
try {
this.wait();
} catch(InterruptedException e) {
System.out.println(e.getMessage());
}
}
isEmpty=true;
this.notify();
System.out.println( "getting "+value);
return value;
}
}
class Sender extends Thread {
private Buffer bf;
public Sender(Buffer bf) {
this.bf=bf;
}
public void run() {
for(int i=1;i <100;i++) {
bf.put(i);
}
}
public static void main(String args[]) {
Buffer bbb=new Buffer();
(new Sender(bbb)).start();
(new Receiver(bbb)).start();
}
}
class Receiver extends Thread {
private Buffer bf;
public Receiver(Buffer bf) {
this.bf=bf;
}
public void run() {
for(int i=1;i <100;i++)
bf.get();
}
}
你看看我的程序就知道了
之所以你会出现那种情况,是因为语句和语句之间也有可能被线程调度所隔开
现在我把它们放到put和get方法里面去,你就可以看到,它们确实是同步的了
[解决办法]
问题在你的生产者和消费者线程.
你的程序的输出是在生产者和消费者线程的里面,
而这两个线程没有采取任何方式同步,当然就会出现打印的那种情况,因为线程的执行是随机的.
这种同步实在是令人费解,同步的是Buffer,却在Sender和Recevier上输出.
我感觉这么理解不是很准确,应该从对象锁的角度去考虑会更好一些.
当一个线程(a)去执行一个对象的同步方法时,就会获得该对象的锁,每个对象有切只有一把锁,
所以其他线程(b)在执行该对象的同步方法时,只能进入该对象的锁等待池,当线程(a)释放了对象的锁后,会从该对象的锁等待池选择一个线程执行.
执行wait()方法会将执行该方法的线程放入该对象的等待池中.
执行notify()方法将唤醒该对象等待池中的一个线程转入到该对象的锁池中.