在学同步时候练习用的
目的是:pro put 0
con get 0
pro put 1
con get 1
...
但是做出来后发现运行结果是随机的~虽然有时候能对上
求教错在哪里?我怀疑两个synchronized方法是不是用的一个this的锁
但是我看不出怎么改
求教求教 代码如下:
public class Wait
{
public static void main(String[] args)
{
Queue q = new Queue();
Producer pro = new Producer(q);
Consumer con = new Consumer(q);
pro.start();
con.start();
}
}
class Queue
{
int value;
boolean full = false;
public synchronized void input(int i)
{
if(!full)
{
value=i;
full=true;
notify();
}
else
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public synchronized int output()
{
if(!full)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
full = false;
notify();
}
return value;
}
}
class Producer extends Thread
{
Queue q;
Producer(Queue q)
{
this.q = q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.input(i);
System.out.println("Producer input "+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this.q = q;
}
public void run()
{
while(true)
{
System.out.println("Consumer get "+q.output());
}
}
}
目的是:pro put 0
con get 0
pro put 1
con get 1
...
但是做出来后发现运行结果是随机的~虽然有时候能对上
求教错在哪里?我怀疑两个synchronized方法是不是用的一个this的锁
但是我看不出怎么改
求教求教 代码如下:
public class Wait
{
public static void main(String[] args)
{
Queue q = new Queue();
Producer pro = new Producer(q);
Consumer con = new Consumer(q);
pro.start();
con.start();
}
}
class Queue
{
int value;
boolean full = false;
public synchronized void input(int i)
{
if(!full)
{
value=i;
full=true;
notify();
}
else
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public synchronized int output()
{
if(!full)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
full = false;
notify();
}
return value;
}
}
class Producer extends Thread
{
Queue q;
Producer(Queue q)
{
this.q = q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.input(i);
System.out.println("Producer input "+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this.q = q;
}
public void run()
{
while(true)
{
System.out.println("Consumer get "+q.output());
}
}
}
public class Wait {
public static void main(String[] args) {
Queue q = new Queue();
Producer pro = new Producer(q);
Consumer con = new Consumer(q);
pro.start();
con.start();
}
}class Queue {
int value;
boolean full = false; public synchronized void input(int i) {
if (!full) {
value = i;
full = true;
notify();
} else {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
} } public synchronized int output() {
if (!full) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
} } else {
full = false;
notify();
}
return value;
}
}class Producer extends Thread {
Queue q; Producer(Queue q) {
this.q = q;
} public void run() {
for (int i = 0; i < 10; i++) {
synchronized (this) {
while (q.full == true);
q.input(i);
System.out.println("Producer input " + i);
}
} }
}class Consumer extends Thread {
Queue q;
Consumer(Queue q) {
this.q = q;
} public void run() {
while (true) {
synchronized (this) {
while (q.full == false) ;
int temp = q.output();//这里顺便将值保存起来,以便退出这个线程,否则你的CPU很生气
System.out.println("Consumer get " + temp);
if(temp >=9) System.exit(0);
}
} }
}
public static void main(String[] args) {
Queue q = new Queue();
Producer pro = new Producer(q);
Consumer con = new Consumer(q);
pro.start();
con.start();
}
}class Queue {
int value;
boolean full = false; public synchronized void input(int i) {
while (full) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
value = i;
full = true;
notify(); } public synchronized int output() { while (!full) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
full = false;
notify();
return value;
}
}class Producer extends Thread {
Queue q; Producer(Queue q) {
this.q = q;
} public void run() {
for (int i = 0; i < 10; i++) {
q.input(i);
System.out.println("Producer input " + i);
}
}
}class Consumer extends Thread {
Queue q; Consumer(Queue q) {
this.q = q;
} public void run() {
while (true) {
System.out.println("Consumer get " + q.output());
}
}
}
老师给的答复是因为 class Queue 没有被锁
所以可能当执行到 boolean full = false 时时间片到期 切换到另一进程
另一进程 采用了 full=false 导致随机和出错
q.input(i);
System.out.println("Producer input "+i);这两段代码间随时都有可能有其他线程插入了,这也必须得同步。
你参考下下面的代码吧,可以达到你的要求public class Wait {
public static void main(String[] args) {
Queue q = new Queue();
Producer pro = new Producer(q);
Consumer con = new Consumer(q);
con.setDaemon(Boolean.TRUE.booleanValue());
pro.start();
con.start();
}
}class Queue {
int value;
boolean full = false; public synchronized void input(int i) {
while (full) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
value = i;
full = true;
System.out.println("Producer input " + value);
notify(); } public synchronized int output() { while (!full) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
full = false;
System.out.println("Consumer get " + value);
notify();
return value;
}
}class Producer extends Thread {
Queue q; Producer(Queue q) {
this.q = q;
} public void run() {
for (int i = 0; i < 10; i++) {
q.input(i);
}
}
}class Consumer extends Thread {
Queue q; Consumer(Queue q) {
this.q = q;
} public void run() {
while (true) {
q.output();
}
}
}
你要怎样的结果呢?//一楼是参考生产者,消费者模型 改装楼主的程序,其中
class Producer extends Thread {
Queue q;
Producer(Queue q) {
this.q = q;
}
public void run() {
for (int i = 0; i < 10; i++) {//在有限时间里,他只能生产10个产品
synchronized (this) {
while (q.full == true);//注意旁边有一个分号,指的是产品还没用完就不继续生产东西
q.input(i);
System.out.println("Producer input " + i);
}
}
}
}class Consumer extends Thread {
Queue q;
Consumer(Queue q) {
this.q = q;
}
public void run() {
while (true) {
synchronized (this) {
while (q.full == false) ;//注意旁边有一个分号,指的是没有产品就死等待
int temp = q.output();//这里顺便将值保存起来,以便退出这个线程,否则你的CPU将会很生气
System.out.println("Consumer get " + temp);
if (temp >= 9)//在有限条件里,他只能消费10个产品,消费完就滚
System.exit(0);//安全退出程序
}
}
}
}
/*
Producer input 0
Consumer get 0
Producer input 1
Producer input 2
Consumer get 1
Consumer get 2
Producer input 3
Consumer get 3
Producer input 4
Consumer get 4
Producer input 5
Consumer get 5
Producer input 6
Consumer get 6
Producer input 7
Consumer get 7
Producer input 8
Consumer get 8
Producer input 9
Consumer get 9
*/
//理解错了,终于明白楼主要干嘛,你把它改成这样吧,就能严格按照顺序输出import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Wait3 { public static void main(String[] args) {
new Queue();
}
}class Queue {//既然都涉及full和value,那就把它作為大管家吧,建立exec统一管理生产者,消费者
int value;
boolean full = false;
ExecutorService exec = Executors.newCachedThreadPool();//
Consumer consumer = new Consumer(this);
Producer producer = new Producer(this);
public Queue() {
exec.execute(consumer);
exec.execute(producer);
}
public synchronized void input(int i) {
full = true;
value = i;
} public synchronized int output() {
if (value == 10)//生产消费完 就退出生产者和消费者
exec.shutdownNow();
full = false;
return value;
}
}/////////////////////////////////////////////////////////////////////////////
class Producer extends Thread {
Queue q;
private int i = -1;
Producer(Queue q) {
this.q = q;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (q.full == true)
wait();// 等待
i++;
synchronized (q.consumer) {//软禁消费者
q.input(i);
System.out.println("Producer input " + i);
q.consumer.notifyAll();//唤醒
}
}
}
} catch (Exception e) {
}
}
}// ///////////////////////////////////////////////////////
class Consumer extends Thread {
Queue q;
Consumer(Queue q) {
this.q = q;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (q.full == false)
wait();// 等待
}
synchronized (q.producer) {//软禁生产者
System.out.println("Consumer get " + q.output());
q.producer.notifyAll();//唤醒
}
}
} catch (Exception e) {
}
}
}
public static void main(String[] args) {
Queue q = new Queue();
(new Producer(q)).start();
(new Consumer(q)).start(); }
}class Queue {
int value;// 类比一个篮子(共享变量)
boolean full = false;// 篮子空的 public synchronized void input(int i) {
while (full == true)//满足等待条件线程等待,后面语句不执行
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} value = i;// 篮子空了,value获得一个值
System.out.println("Pruducer put " + i);
full = true;// 篮子满了
notify();
} public synchronized void output() {
while (full == false)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Consumer get " + value);
full = false;// 否则篮子置为空
notify();// 唤醒其他线程
}
}class Producer extends Thread {
Queue q; Producer(Queue q) {
this.q = q;
} public void run() {
for (int i = 0; i < 10; i++) {
q.input(i); }
}
}class Consumer extends Thread {
Queue q; Consumer(Queue q) {
this.q = q;
} public void run() {
while (true) {
q.output();
} }
}
//结果
Pruducer put 0
Consumer get 0
Pruducer put 1
Consumer get 1
Pruducer put 2
Consumer get 2
Pruducer put 3
Consumer get 3
Pruducer put 4
Consumer get 4
Pruducer put 5
Consumer get 5
Pruducer put 6
Consumer get 6
Pruducer put 7
Consumer get 7
Pruducer put 8
Consumer get 8
Pruducer put 9
Consumer get 9