Uncle Lei

life is a game for everyone and love is a price.

导航

一个线程同步问题的例子

Posted on 2016-08-24 10:21  chunzai  阅读(1513)  评论(0编辑  收藏  举报

编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z。打印顺序为12A34B56C….5152Z。即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替循环打印,直到打印到整数52和字母Z结束。
要求:
编写打印类Printer,声明私有属性index,初始值为1,用来表示是第几次打印。
在打印类Printer中编写打印数字的方法print(int i),3的倍数就使用wait()方法等待,否则就输出i,使用notifyAll()进行唤醒其它线程。
在打印类Printer中编写打印字母的方法print(char c),不是3的倍数就等待,否则就打印输出字母c,使用notifyAll()进行唤醒其它线程。
编写打印数字的线程NumberPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出数字的方法。
编写打印字母的线程LetterPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出字母的方法。
编写测试类Test,创建打印类对象,创建两个线程类对象,启动线程。

 1 public class TestPrint {
 2 public static void main(String[] args) {
 3 Printer p = new Printer();
 4 LetterPrinter lp = new LetterPrinter(p);
 5 NumberPrinter np = new NumberPrinter(p);
 6 lp.start();
 7 np.start();
 8 }
 9 }
10 
11 class Printer {
12 int index = 1;
13 public void print(int i) {
14 while(index<=78) {
15 if(index%3==0) {
16 try {
17 this.notifyAll();
18 this.wait();
19 } catch (InterruptedException e) {
20 e.printStackTrace();
21 }
22 }else {
23 System.out.print(i++);
24 index++;
25 }
26 }
27 }
28 
29 public void print(char c) {
30 while(index<=78) {
31 if(index%3==0) {
32 System.out.print(c++);
33 index++;
34 }else {
35 this.notifyAll();
36 try {
37 this.wait();
38 } catch (InterruptedException e) {
39 e.printStackTrace();
40 }
41 }
42 }
43 }
44 }
45 
46 class LetterPrinter extends Thread{
47 private Printer p;
48 public LetterPrinter(Printer p) {
49 this.p = p;
50 }
51 public void run() {
52 p.print('A');
53 }
54 }
55 
56 class NumberPrinter extends Thread{
57 private Printer p;
58 public NumberPrinter(Printer p) {
59 this.p = p;
60 }
61 
62 public void run() {
63 p.print(1);
64 }
65 }

 

结果为:

Exception in thread "Thread-0" 12Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at TestThread.Printer.print(TestPrint.java:19)
at TestThread.NumberPrinter.run(TestPrint.java:65)
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at TestThread.Printer.print(TestPrint.java:37)
at TestThread.LetterPrinter.run(TestPrint.java:54)

  

加了synchronized之后就可以运行了,试试看:

public class TestPrint {
public static void main(String[] args) {
Printer p = new Printer();
LetterPrinter lp = new LetterPrinter(p);
NumberPrinter np = new NumberPrinter(p);
lp.start();
np.start();
}
}

class Printer {
int index = 1;
public synchronized void print(int i) {
while(index<=78) {
if(index%3==0) {
try {
this.notifyAll();
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
System.out.print(i++);
index++;
}
}
}

public synchronized void print(char c) {
while(index<=78) {
if(index%3==0) {
System.out.print(c++);
index++;
}else {
this.notifyAll();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

class LetterPrinter extends Thread{
private Printer p;
public LetterPrinter(Printer p) {
this.p = p;
}
public void run() {
p.print('A');
}
}

class NumberPrinter extends Thread{
private Printer p;
public NumberPrinter(Printer p) {
this.p = p;
}

public void run() {
p.print(1);
}
}

 

 

结果为:

12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z