任务要求:
1、使用生产者和消费者模式实现,交替输出:
假设只有两个线程,输出以下结果:
t1-->1
t2-->2
t1-->3
t2-->4
t1-->5
t2-->6
....
要求:必须交替,并且t1线程负责输出奇数。t2线程负责输出偶数。
两个线程共享一个数字,每个线程执行时都要对这个数字进行:++
public class Num {
int i;
}
synchronized(num){
if(num是奇数){
num.wait();
}
// 输出偶数
// notifyAll()
}
synchronized(num){
if(num是偶数){
num.wait();
}
// 输出奇数
// notifyAll();
}
代码实现:
这里是不能使用Integer(Integer i)的,因为Integer虽然是对象类,但是i不能当做同步的锁,因为当i实现i++操作时,原来的Integer对象已经改变了,同步锁失效,所以这里使用了Num类进行了包装,实现的结果的是相同的
package 使用生产者和消费者模式实现交替输出;
public class Num {
private int i;
public Num(int i) {
this.i = i;
}
public Num() {
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
下面是奇数线程类
package 使用生产者和消费者模式实现交替输出;
public class OddNum implements Runnable{
Num num;
public OddNum(Num num) {
this.num = num;
}
public OddNum() {
}
@Override
public void run() {
while(true){
synchronized (num){
if (num.getI()%2==0){
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"---->"+num.getI());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
num.setI(num.getI()+1);
num.notify();
}
}
}
}
下面是偶数线程类
package 使用生产者和消费者模式实现交替输出;
public class EvenNum implements Runnable {
Num num;
public EvenNum(Num num) {
this.num = num;
}
public EvenNum() {
}
@Override
public void run() {
while(true){
synchronized (num){
if (num.getI()%2!=0){
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"---->"+num.getI());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
num.setI(num.getI()+1);
num.notify();
}
}
}
}
最后是测试类
package 使用生产者和消费者模式实现交替输出;
public class Test2 {
public static void main(String[] args) {
Num num=new Num(1);
Thread t1=new Thread(new OddNum(num));
Thread t2=new Thread(new EvenNum(num));
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}
测试结果如下,正确
t1---->1
t2---->2
t1---->3
t2---->4
t1---->5
t2---->6
t1---->7
t2---->8
t1---->9
t2---->10