package com.hzxxb.thread;
public class ThreadTest {
public static void main(String[] args) {
Num n = new Num();
//P p = new P(n);
//C c = new C(n);
Thread p = new P(n);
Thread c = new C(n);
p.setPriority(Thread.MAX_PRIORITY);
p.start();
c.start();
}
}
class P extends Thread {
Num n = null;
public P(Num n) {
this.n = n;
}
public void run() {
for (int i = 0; i < 10; i++) {
/**
 * 差异
 */
n.setI(i);
System.out.println("生产者放入:" + i);
}
}
}
class C extends Thread {
Num n = null;
public C(Num n) {
this.n = n;
}
public void run() {
while (true) {
System.out.println("消费者获取:" + n.getI());
}
}
}
class Num {
private int i;
private boolean isFull = false; public synchronized int getI() {
if (!isFull) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isFull = false;
notify();
return i;
}
public synchronized void setI(int i) {
if (!isFull) {
this.i = i;
isFull = true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果:
消费者获取:0
生产者放入:0
生产者放入:1
消费者获取:1
消费者获取:2
生产者放入:2
消费者获取:3
生产者放入:3
生产者放入:4
消费者获取:4
消费者获取:5
生产者放入:5
生产者放入:6
消费者获取:6
生产者放入:7
消费者获取:7
生产者放入:8
消费者获取:8
消费者获取:9
生产者放入:9
-------------------
以下修改class P{}
class P extends Thread {
Num n = null;
public P(Num n) {
this.n = n;
}
public void run() {
for (int i = 0; i < 10; i++) {
/**
 * 差异
 */
                        System.out.println("生产者放入:" + i);
n.setI(i);

}
}
}
结果为:
生产者放入:0
消费者获取:0
生产者放入:1
消费者获取:1
生产者放入:2
消费者获取:2
生产者放入:3
消费者获取:3
生产者放入:4
生产者放入:5
消费者获取:4
生产者放入:6
消费者获取:5
消费者获取:6
生产者放入:7
消费者获取:7
生产者放入:8
消费者获取:8
生产者放入:9
消费者获取:9这是为何?

解决方案 »

  1.   

    我想是因为,你的set()和get()方法没有同时同步,每次不可能同时有两个线程访问get()方法,但此时其他线程可以访问set()方法,反之set()也是一样,所以就会出现你使用了synchronized ,却不能真正意思的实现同步
      

  2.   

    synchronized是可以实现同步的,但这里并不是这个的问题
    这个是线程的执行先后顺序问题
    优先度高只是在执行过程中cpu的分配概率高,并不表示一定要先被启动执行
      

  3.   

    重构了一下,好象怎么跑都没问题了 ,还是不解上面的现象 ,是不是多cpu的问题public class ThreadTest2 {
    public static void main(String[] args) {
      N n = new N();
              Thread p = new P(n);
              p.setName("生产者");
              
              Thread c = new C(n);
              c.setName("消费者");
              
              p.start();
              p.setPriority(Thread.MAX_PRIORITY);
            
              c.start();
              c.setPriority(Thread.MIN_PRIORITY);       
    }
    }class N {
    private int i;
        private boolean isFull = false ;
        
    public synchronized int getI() {
    if(!isFull){
                try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println(Thread.currentThread().getName() + "取值-->" + i );
    isFull = false ;
        notify();
    return i;
    } public synchronized void setI(int i) {
    if(!isFull){
    System.out.println(Thread.currentThread().getName() + "放值-->" + i );
    this.i = i;
    isFull = true ; 
    notify();
    }
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }class P extends Thread {
    private N n; public P( N n) {
    this.n = n;
    } public void run() {
    for (int i = 0; i < 10; i++) {
    n.setI(i);
    }
    }
    }class C extends Thread {
    private N n; public C( N n) {
    this.n = n;
    } public void run() {
    while(true) {
    n.getI();
    }
    }
    }
      

  4.   

    class C extends Thread {
    Num n = null;
    public C(Num n) {
    this.n = n;
    }
    public void run() {
    while (true) {
    System.out.println("消?者?取:" + n.getI());
    try{
    sleep(10);
    }
    catch(InterruptedException e){}
    }
    }
    }
      

  5.   

    我觉得是线程切换的问题:尽管C的优先级低,但C在running,这时P就绪,但并不意味P立即就运行,这里有系统调度的问题,程序控制不了吧。