public class MyWait {
public static void main(String[] args) {
Containers cs = new Containers();
Consumer con = new Consumer(cs);
Producer p = new Producer(cs);
Thread c1 = new Thread(con);
Thread c2 = new Thread(p);
c2.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
c1.start();
}
}
class Containers{
int count = 1;
int index = 1;
public synchronized void put() {
System.out.println("put..."+(++index));
if(index == 2) {
try {
System.out.println("p.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("put-wait."+count++);
notify();
System.out.println("notify-put!"+count++);
}
public synchronized void get() {
System.out.println("get..."+(--index));
if(index == 1) {
try {
System.out.println("g.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("get-wait."+count++);
notify();
System.out.println("get-afer-notify!"+count++);
}
}class Consumer implements Runnable{
Containers cs;
Consumer(Containers cs) {
this.cs = cs;
}
public void run() {
while(true) {
cs.get();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}class Producer implements Runnable{ Containers cs;
Producer(Containers cs) {
this.cs = cs;
}
public void run() {
while(true) {
cs.put();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
请问这短代码说明地方有问题?
两个线程都wait()住了
一个线程分别都只执行一次;
结果为:
put...2
p.
get...1
g.
public static void main(String[] args) {
Containers cs = new Containers();
Consumer con = new Consumer(cs);
Producer p = new Producer(cs);
Thread c1 = new Thread(con);
Thread c2 = new Thread(p);
c2.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
c1.start();
}
}
class Containers{
int count = 1;
int index = 1;
public synchronized void put() {
System.out.println("put..."+(++index));
if(index == 2) {
try {
System.out.println("p.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("put-wait."+count++);
notify();
System.out.println("notify-put!"+count++);
}
public synchronized void get() {
System.out.println("get..."+(--index));
if(index == 1) {
try {
System.out.println("g.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("get-wait."+count++);
notify();
System.out.println("get-afer-notify!"+count++);
}
}class Consumer implements Runnable{
Containers cs;
Consumer(Containers cs) {
this.cs = cs;
}
public void run() {
while(true) {
cs.get();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}class Producer implements Runnable{ Containers cs;
Producer(Containers cs) {
this.cs = cs;
}
public void run() {
while(true) {
cs.put();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
请问这短代码说明地方有问题?
两个线程都wait()住了
一个线程分别都只执行一次;
结果为:
put...2
p.
get...1
g.
解决方案 »
- java对SQL2005数据表打包的一些问题,急急急
- 求一个SQL语句
- 用哪个类可以获得CPU信息?
- 请指教(求):一个swt的图形窗口怎样通过tomcat服务器调用sqlserver2000中的数据?
- 急!!!关于BIRT和MYSQL之间的中文问题!!!有用MYSQL做过BIRT的朋友指点啊!!
- 怎么样,让一个GUI图形界面不能改变大小(不能让大小化按钮失效)
- 大家好,小弟初学编程序(J2ME),请教一些关于调试方面的问题(JbuilderX)
- 负载平衡。。。。
- jTabbedPane里面怎么可以把一个图形加进去。
- 关于jboss+tomcat与数据库连接测试结果,请大家讨论一下。。
- Java 图像处理需求
- Mina2开发网络通讯
System.out.println("get..."+(--index));
if(index == 1) {
try {
System.out.println("g.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("get-wait."+count++);
notify();
System.out.println("get-afer-notify!"+count++);
}
}-----------------------------------
index ==0 才对。
线程c1执行cs对象的get方法时,index=1执行this.wait方法,失去了对象cs控制锁,线程c1也无法执行下去了。
建议代码改为如下:class Containers { int count = 1;
int index = 0; public synchronized void put() {
System.out.println("put..." + (++index));
if (index == 2) {
try {
System.out.println("p.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("put-wait." + count++);
this.notify();
System.out.println("notify-put!" + count++);
} public synchronized void get() {
System.out.println("get..." + (--index));
if (index == 0) {
try {
System.out.println("g.");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("get-wait." + count++);
this.notify();
System.out.println("get-afer-notify!" + count++);
}
}
public static void main(String[] args) {
Queue q=new Queue ();//new出一个q:后面的两个线程都是用的同一个q,保证一个put一个get
Producer p=new Producer (q);//让new出的p去往q里面put
Customer c=new Customer (q);//让new出的c从q中get
p.start();//p和q开始的顺序并不报错
c.start();
}
}
class Producer extends Thread
{
Queue q;
public Producer(Queue q) {
this.q=q;//给成员变量赋值,再一调运q的put方法
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
q.put(i);//此处只是让q去put 10次
System.out.println("Producer put "+i);//并且输出本次放的是第几杯
}
}
}
class Customer extends Thread
{
Queue q;
public Customer(Queue q) {
this.q=q;//给成员变量赋值,再一调运q的get方法
}
@Override
public void run() {
while (true) {//死循环:只要q里面有,就去get
//get方法有返回值,返回值就是producer所put的数量
//此处也不需要去考虑是第几杯
//在Queue中的value解决可这一问题:
//put中的I赋给value,get方法有返回值就value的值
System.out.println("Customer get "+q.get());
//如果循环完了,就跳出循环,否则线程不会自己结束
if (q.value==9) {
break;
}
}
}
}
class Queue
{
int value;
boolean bFull=false;
public synchronized void put (int i)//在producer中的put方法中就是将其I传进来
{
if (!bFull) {//条件为真(如果没满,就倒水)
value=i;//给value赋值,现在有几杯水
bFull=true;//满了
notify();//唤醒其他线程(让customer去get)
}
try {
wait();//告诉customer去get后自己等待customer的get结束
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized int get()
{
if (!bFull) {//如果没满就等待,如果满了就不进 **这就是为什么main里面谁先开始不报错的原因**
//get和put方法中的if条件判断起到了至关重要的作用
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bFull =false;//赋值为没满
notify();//唤醒producer去put
return value;//get的返回值就是put的时候给value赋的值
}
}