//程序是关于两个对象同时访问另一个对象里的数据成员
public class C13_4 {
public static void main(String[] args){
HoldInt h=new HoldInt();
ProduceInt p=new ProduceInt(h);
ConsumeInt c=new ConsumeInt(h);
p.start();
c.start();
}
}
class HoldInt{
private int sharedInt;
private boolean writable=true; //writable为true时,只有 ProduceInt的对象可以访问
public synchronized void set(int val){
while(!writable){ //writable为false时,线程就等待
try{wait();}catch(InterruptedException e){
e.printStackTrace();
}
}
writable=false;
sharedInt=val;
notify();
}
public synchronized int get(){
while(writable){ //writable为false时,线程就等待
try{wait();}catch(InterruptedException e){
e.printStackTrace();
}
}
writable=true;
notify();
return sharedInt;
}
}class ProduceInt extends Thread{
private HoldInt hi;
public ProduceInt(HoldInt hiForm){
hi=hiForm;
}
public void run(){
for(int i=1;i<=4;i++){
hi.set(i);
System.out.println("产生的数据是:"+i);
}
}
}
class ConsumeInt extends Thread{
private HoldInt hi;
public ConsumeInt(HoldInt hiForm){
hi=hiForm;
}
public void run(){
for(int i=1;i<=4;i++){
int val=hi.get();
System.out.println("读取的数据是:"+val);
}
}
}运行结果:
产生的数据是:1
产生的数据是:2
读取的数据是:1
产生的数据是:3
读取的数据是:2
产生的数据是:4
读取的数据是:3
读取的数据是:4运行结果的红色部分不理解。我认为打印完“产生的数据是:1”这句话后,p对象所在的线程将等待,c对象所在的线程将就绪并运行,所以打印第二句话应该是“读取的数据是:1”。
但我的理解却是错的,请告诉我我错在哪里,谢谢!
解决方案 »
- 请问java内存布局如何查看?
- 难道内部类里面就不能再有内部类吗?一个登陆按钮的问题!
- 关于站网在tomcat中运行找不到类的问题~!初学者..请各位指点
- AES加密解密JAVA實現
- 急救!为什么getText(),getPassword()方法不能识别呢?输入的帐号和密码程序不响应呢?
- 为什么窗口最大化或者拉大窗口都不触发paint啊?
- 面试题:求教数字连连看算法!
- 我有一定的C++基础,我现在想学另一种语言.例如java,delphi等,应该学那个呢?java又是什么东西?用于开发软件的工具吗?java的本意和精华在那
- 怎样将XML或者HTML转成EXCEL文件??
- 一个多线程搜索主机名(或IP地址)的问题
- 急!关于java的原始数据类型及其封装类
- NetBeanse编译类的问题,
永远不要假设一个线程会在另一个线程执行之前执行某些动作,除非你已经使用了同步以强制一个特定的顺序。
在这里你可以在生产的时候让进程先休眠一小会,然后让消费的进程也休眠一小会,但是应该让生产进程休眠的时间大于消费进程休眠的时间。给个例子你参考一下:
class ProduceInt extends Thread{
private HoldInt hi;
public ProduceInt(HoldInt hiForm){
hi=hiForm;
}
public void run(){
for(int i=1;i<=4;i++){
hi.set(i);
System.out.println("产生的数据是:"+i);
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ConsumeInt extends Thread{
private HoldInt hi;
public ConsumeInt(HoldInt hiForm){
hi=hiForm;
}
public void run(){
for(int i=1;i<=4;i++){
int val=hi.get();
System.out.println("读取的数据是:"+val);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}这样的话,大多时候应该是正确的结果。不知道正确与否,我也没学多少,希望能给你点启示。
然后再分析一下为什么,你也许就知道了。