//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;
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呢?
请教啦
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方法里面去,你就可以看到,它们确实是同步的了
具体到我的例子中,因为上了锁,所以get方法和put方法一定会被执行
后面的语句就可能被线程切割到后面执行?
程序先运行Sender线程 写入了一个数字
然后运行Receiver线程,在运行这个线程的时候,首先i=1,然后先运算括号里的参数方法bf.get()。这样一来的话,这个方法执行完前,如果再调用Sender线程是会被等待的。那么也就是说get方法一定会被执行完,那么return value语句一定会被执行。
然后才可能继续执行Sender线程
我这样理解,对么?
而这两个线程没有采取任何方式同步,当然就会出现打印的那种情况,因为线程的执行是随机的.
这种同步实在是令人费解,同步的是Buffer,却在Sender和Recevier上输出.我感觉这么理解不是很准确,应该从对象锁的角度去考虑会更好一些.
当一个线程(a)去执行一个对象的同步方法时,就会获得该对象的锁,每个对象有切只有一把锁,
所以其他线程(b)在执行该对象的同步方法时,只能进入该对象的锁等待池,当线程(a)释放了对象的锁后,会从该对象的锁等待池选择一个线程执行.
执行wait()方法会将执行该方法的线程放入该对象的等待池中.
执行notify()方法将唤醒该对象等待池中的一个线程转入到该对象的锁池中.