多线程求解

j2eeoriented 2009-04-22 12:14:19
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

这是为何?

...全文
184 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
scpaph606 2009-04-22
  • 打赏
  • 举报
回复
我想是因为,你的set()和get()方法没有同时同步,每次不可能同时有两个线程访问get()方法,但此时其他线程可以访问set()方法,反之set()也是一样,所以就会出现你使用了synchronized ,却不能真正意思的实现同步
scpaph606 2009-04-22
  • 打赏
  • 举报
回复
虽然我不知道答案,顶一下
j2eeoriented 2009-04-22
  • 打赏
  • 举报
回复
就上面我发现让两者中的任一个暂眠都是有规律的 至于没规律的原因还没找到
msgsnd 2009-04-22
  • 打赏
  • 举报
回复
我觉得是线程切换的问题:尽管C的优先级低,但C在running,这时P就绪,但并不意味P立即就运行,这里有系统调度的问题,程序控制不了吧。
msgsnd 2009-04-22
  • 打赏
  • 举报
回复
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){}
}
}
}
j2eeoriented 2009-04-22
  • 打赏
  • 举报
回复
重构了一下,好象怎么跑都没问题了 ,还是不解上面的现象 ,是不是多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();
}
}
}
qybao 2009-04-22
  • 打赏
  • 举报
回复
synchronized是可以实现同步的,但这里并不是这个的问题
这个是线程的执行先后顺序问题
优先度高只是在执行过程中cpu的分配概率高,并不表示一定要先被启动执行
YHL27 2009-04-22
  • 打赏
  • 举报
回复
学习
j2eeoriented 2009-04-22
  • 打赏
  • 举报
回复
1.优先级明显不可靠?
2.不同的地方只是换了下位置,结果就乱来了?
zhouxingyu896 2009-04-22
  • 打赏
  • 举报
回复
学习

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧