各们高人,小弟现在遇到一个关于Java同步的问题:
一个生产线程(P)负责生产,消费线程(C)负责消费,只有当条件满足(C所拥有的金额超过100元)时才可以消费,比如:第一次P给了50元,所以C还要等P在给50才可以消费,但P下次可能给100也可能给出10元,如果给出100的话,C可以消费了,然后把余下的50存下来;当P给出10元时,C继续等待,如果超过3秒,C就不等了,并且把手中的50+10元也不要了,此时C手中余0元.P继续C也继续.
问下这个问题怎么解决啊?
一个生产线程(P)负责生产,消费线程(C)负责消费,只有当条件满足(C所拥有的金额超过100元)时才可以消费,比如:第一次P给了50元,所以C还要等P在给50才可以消费,但P下次可能给100也可能给出10元,如果给出100的话,C可以消费了,然后把余下的50存下来;当P给出10元时,C继续等待,如果超过3秒,C就不等了,并且把手中的50+10元也不要了,此时C手中余0元.P继续C也继续.
问下这个问题怎么解决啊?
public class ProducerConsumer { public static void main(String[] args) {
SynchronizedStack ss = new SynchronizedStack();
Producer p = new Producer(ss); // 产生一个生产者
Consumer c = new Consumer(ss); // 产生一个消费者
new Thread(p).start(); // 启动生产者线程
new Thread(c).start(); // 启动消费者线程
}}class Bread // 定义生产面包
{
int id; Bread(int id) {
this.id = id;
} public String toString() // 重写toString方法
{
return "bread :" + id;
}
}class SynchronizedStack // 定义一个盛面包的容器
{
int index = 0;
Bread[] bread = new Bread[6]; public synchronized void putIn(Bread bread) // 放进方法
{
while (index == this.bread.length) {
try {
this.wait(); // 只针对synchronized
// Object对象的wait()方法,表示调用当前对象的wait()方法,运行当前对象的此方法的线程等待,直到被notify()唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify(); // 唤醒一个wait的线程
// this.notifyAll();//唤醒所有wait的线程
this.bread[index] = bread;
index++;
} public synchronized Bread putOut() // 拿出方法
{
while (index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify(); // 唤醒一个wait的线程
// this.notifyAll();//唤醒所有wait的线程
index--;
return bread[index];
}
}class Producer implements Runnable {
SynchronizedStack ss = null; Producer(SynchronizedStack ss) {
this.ss = ss;
} public void run() {
for (int i = 0; i < 30; i++) {
Bread bread = new Bread(i);
ss.putIn(bread);
System.out.println("生产了 :" + bread);
try {
// Thread.sleep(1000);
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}class Consumer implements Runnable { SynchronizedStack ss = null; Consumer(SynchronizedStack ss) {
this.ss = ss;
} public void run() {
for (int i = 0; i < 30; i++) {
Bread bread = ss.putOut();
System.out.println("消费了 :" + bread);
try {
// Thread.sleep(1000);
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package test.thread;
public class Producer extends Thread {
private int number;
private Share shared;
public Producer(Share s, int number) {
shared = s;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
shared.put(i);
System.out.println("生产者" + this.number + "输出的数据为:" + i);
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {}
}
}
public static void main(String args[]) {
Share s = new Share();
Producer p = new Producer(s, 1);
Consumer c = new Consumer(s, 1);
p.start();
c.start();
}
}
class Consumer extends Thread {
private int number;
private Share shared;
public Consumer(Share s, int number) {
shared = s;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = shared.get();
System.out.println("消费者" + this.number + "得到的数据:" + value);
}
}
}
class Share {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {}
}
contents = value;
available = true;
notifyAll();
}
}
public class Producyter_buyer {
private int size = 4;
private int remain = size; public static void main(String[] args) {
Producyter_buyer pb = new Producyter_buyer();
pb.start();
} public void start() {
producter p = new producter();
buyer b = new buyer();
p.start();
b.start();
}
class producter extends Thread {
public void run() {
for (int i = 0; true; i++) {
product(i);
try {
this.sleep((int) Math.random() * 5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class buyer extends Thread {
public void run() {
for (int i = 0; true; i++) {
buy(i);
try {
this.sleep((int) Math.random() * 5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} public synchronized void product(int i) {
while (remain < this.size) {
remain++;
System.out.println("被生产,库存为----------------------->" + remain);
if (remain >= this.size) {
System.out.println("生产停止,库存满为" + remain);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
} public synchronized void buy(int i) {
while (remain <= this.size) {
remain--;
System.out.println("被消费,库存为----------------------->" + remain);
if (remain <= 1) {
System.out.println("消费停止,库存仅为" + remain);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
}
}
}
import java.util.*;
class Test7
{
public static void main(String[] args)
{
final T t = new T();
Thread thread1 = new Thread(new Runnable() //生产线程
{
public void run()
{
while(true)
{ t.product();
}
}
});
Thread thread2 = new Thread(new Runnable() //消费线程
{
public void run()
{
while(true)
{
t.consume();
}
}
});
thread1.start(); //运行生产线程
thread2.start(); //运行消费线程
}}class T
{
int n = 0; //库存量,从0开始
int p; //生产的数量
Random r = new Random();
double time; //时间
boolean b = false;
synchronized void product()
{
time = System.currentTimeMillis(); //开始计时
try
{
/*Thread.currentThread().sleep(1000);
*这里注释起来了,你可以测试一下时候超过3秒就全部消费。我试了,好使
*/
if(b)
{
wait();
}
}
catch(Exception e){System.out.println(e);}
p =(r.nextInt(100))+1; //从1-100 随即生产
n = n + p; //库存量在增加
System.out.println("生产了:"+p+"当前总数为"+n);
b = true;
notify();
}
synchronized void consume()
{
try
{
if(!b)
{
wait();
}
}
catch(Exception e){System.out.println(e);} if(n>=100)
{
n = n - p;
System.out.println("消费 :" + p+"剩余:"+n);//超过100时,把上次所生产的都消费掉
}
else if(System.currentTimeMillis() >= (time+3000))//当前时间大于开始生产时的时间3秒时执行
{
System.out.println("超过3秒,全部消费,共消费:"+ n);
n = 0;
}
b = false;
notify();
}
}
这个是按照,超过100就消费掉当次所生产的数。反正我看你的题目是这么理解的。
这样运行到最后库存量就一直是99,你只要一生产就马上被消费掉了。。我试了,你要不控制生产速度,以计算机的运行速度,一辈子也达不到超过3秒还没到100的时候。
所以那里注释起来控制下生产速度吧。
sleep()是挂起线程。让线程暂时停止。好象没有计时的功能啊。
*
*/
package houlei.test;import java.util.Random;/**
* @author 侯磊
*
*/
public class P extends Thread { private C c;
public P(C c){
this.c=c;
}
public void run(){
Random rand = new Random();
while(true){
int m = rand.nextInt(200);
c.add(m);
System.out.println("P::"+m);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
C c = new C();
P p = new P(c);
p.start();
c.start();
}}
*
*/
package houlei.test;/**
* @author 侯磊
*
*/
public class C extends Thread { private long timeout = 1000*3;
private int money=0;
public synchronized void add(int m){
money+=m;
notify();
}
private synchronized int getMoney(){
if(money>=100){
money-=100;
return 100;
}else{
try {
wait(timeout);
} catch (InterruptedException e) {}
if(money>=100){
money-=100;
return 100;
}else{
money=0;
return 0;
}
}
}
public void run(){
while(true){
System.out.println("C::"+getMoney());
}
}}
若任何时候,只要钱不足100元就最多等待3秒钟,则很简单了。若必须是P的第二次给付开始时,C才定时,最多等待不超过3秒钟,则楼上诸位的代码全是错误的。另:
1)牢牢记住:不要在synchronized代码块中调用sleep(..),千万不要这样设计程序。
2)wait()的等待条件记住要用while()等循环判,不要用if()去判。楼主的真正需求到底是什么呢?否则没有办法去写这个程序。