to yinwenjie(java入门中) 你完全错误!! 线程【必须】使用start方法启动,Sun只是不建议使用stop方法来停止线程线程的start方法你不应该去覆盖,你的代码只是应该覆盖run方法,你调用thread.start的时候 JVM会启动一个线程来开始执行run方法直到它退出为止
to ChDw(米) :哈哈哈,使我字打错了,应该是“我改过了”,我手误打成了“我盖过了”。多谢老兄了,我初学者,还希望大家多多指点啊!
to cs_tar() :谢谢,但如果我在producer中定义了一个新的customer类对象,那么在Course2类中就存在了两个customer对象了,而wait(),notify()方法不是静态方法,也就是说这两个对象的阻塞、就绪状态相互独立。我想错误还是应该在while循环中,我看书上说的while循环在线程中非常自私,不知道是不是这样?
MyCustomer.start();start才是启动线程的方法,start的内部会自动去开始执行run方法的
大家再帮我看看吧....
wait是在一个对象上等待
需要这个对象调用notify()去唤醒
你好好看看wait和notify吧
我把你的代码改了
现在好使了
public synchronized void add(){
Course2.productionNumber++;
System.out.println("produce = " + productionNumber);
try{
// notify();
this.notifyAll();
}
catch(Exception e){
}
if(productionNumber >= 10){
try{
this.wait();
}
catch(Exception e){
}
}
}
public synchronized void minus(){
System.out.println("i'm the customer");
if(productionNumber > 0){
productionNumber--;
System.out.println("consume = " + productionNumber);
}
else{
try {
this.wait();
} catch (InterruptedException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
} }
}
public synchronized void produce(){
add();
}
public synchronized void consume(){
minus();
}
我是在还没确定错误时试着看的
notify()是唤起一个线程
我用notifyAll()来唤起所有线程
在你这里在一个时刻只有一个线程在等待
本题中wait()实际上是this.wait(),他用的锁是各自的类实例,即MyProducer,MyCustomer,两个地方用的锁不一样,从而导致notify()无法通知wait()。可做如下改动:
在course2类下:private Object valueLock = new Object();每次调用wait()或notify()时如下处理:synchronized ( valueLock ) {
try {
valueLock.notify();//或wait()
}
线程【必须】使用start方法启动,Sun只是不建议使用stop方法来停止线程线程的start方法你不应该去覆盖,你的代码只是应该覆盖run方法,你调用thread.start的时候
JVM会启动一个线程来开始执行run方法直到它退出为止
try{
wait();
}
catch(Exception w){
System.out.println("Exception!!");
}
}
改成while(productionNumber<=0){
synchronized(valuelock)
{
try{
valuelock.wait();
}
catch(Exception w){
System.out.println("Exception!!");
}
}就可以了。
锁是加在对象上的
一个线程运行需要取得一个对象的锁
楼主开始时的锁是加的两个对象producer和custmer上了
producer通知等待producer的锁的进程,不会去通知等待custmer的进程
custmer通知等待custmer的锁的进程,它也不会去通知等待producer的进程
而那个producer、custmer线程等待的是它自己的锁
他们谁也不会去通知其他人
我改过以后的是把锁加在了那个course2上的
完整代码如下:
public class Course2 {
private static int productionNumber = 1;//用于记录已生产的但还未消费的产品个数
/**
* 生产者类,用线程方式不停的生产产品,
* */
public synchronized void add(){
Course2.productionNumber++;
System.out.println("i'm the produce");
System.out.println("produce = " + productionNumber);
try{
// notify();
this.notifyAll();
}
catch(Exception e){
}
if(productionNumber >= 10){
try{
this.wait();
}
catch(Exception e){
}
}
}
public synchronized void minus(){
System.out.println("i'm the customer");
if(productionNumber > 0){
productionNumber--;
System.out.println("consume = " + productionNumber);
this.notify();
}
else{
try {
this.wait();
} catch (InterruptedException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
} }
}
public class producer extends Thread{
/**
* 构建起用于初始化一些属性
* */
public producer(){
}
/**
* 此方法用于生产者不停的生产产品
* */
public synchronized void produce(){
add();
}
/**
* 覆盖run方法
* */
public void run(){
while(true){
this.produce();
try {
sleep(700);
} catch (InterruptedException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
}
}
/**
* 消费者类,用于在productionNumber != 0的情况下消费产品
* */
public class customer extends Thread{
/**
* 构建器用于处理一些属性
* */
public customer(){
}
/**
* 此方法用于消费者消费产品
* */
public synchronized void consume(){
minus();
}
/**
* 覆盖run方法
* */
public void run(){
while(true){
this.consume();
try {
sleep(900);
} catch (InterruptedException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
}
}
public static void main(String[] src){
Course2 MyCourse2 = new Course2();
Course2.producer MyProducer = MyCourse2.new producer();//生产者对象
Course2.customer MyCustomer = MyCourse2.new customer();//消费者对象
MyProducer.setPriority(Thread.MAX_PRIORITY);
MyCustomer.setPriority(Thread.MIN_PRIORITY);
MyProducer.start();
MyCustomer.start();
}
}