线程间通信的问题
Issues in communication between threads
我正在尝试解决下述问题。
编写一个从执行开始就打印消息的程序,另一个线程每第十五条消息打印一条消息。当打印每条消息时,让消息打印线程通知消息打印线程。添加另一个线程,每七条消息打印一条不同的消息,而不修改消息打印线程。
我尝试了以下方法。任何人都可以指导我如何调用程序中的特定线程。
这个class用于
public class Message{
String message;
volatile boolean flag=true;
synchronized void printMessage(String message){
int count=16;
for(int i=0;true;){
i++;
if(i%15==0 || i%7==0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i +" "+message);
notify();
}
}
synchronized void printMessageFifteen(String message){
System.out.println(message);
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
synchronized void printMessageSeven(String message){
System.out.println(message);
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
以连续方式打印消息的线程:
public class ContinousMessageThread extends Thread{
Message messageObject;
ContinousMessageThread(Message messageObject){
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
messageObject.printMessage(this.messageObject.message);
}
}
每十五秒打印一次消息的线程:
public class FifteenSecondsMessageThread extends Thread{
Message messageObject;
public FifteenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageFifteen("Fifteen Seconds over");
}
}
}
每七秒打印一次消息的线程
public class SevenSecondsMessageThread extends Thread {
Message messageObject;
public SevenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageSeven("Seven Seconds over");
}
}
}
Main class 所有线程启动的地方..
public class MainClass {
public static void main(String[] args) {
Object sevenSecond= new Object();
Object fifteenSecond= new Object();
Message messageObject= new Message();
messageObject.message="seconds";
ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject);
}
我得到的输出:
1 seconds
2 seconds
3 seconds
4 seconds
5 seconds
6 seconds
Seven Seconds over
7 seconds
8 seconds
9 seconds
10 seconds
11 seconds
12 seconds
13 seconds
Seven Seconds over
14 seconds
Seven Seconds over
15 seconds
16 seconds
17 seconds
18 seconds
19 seconds
20 seconds
Seven Seconds over
21 seconds
22 seconds
23 seconds
24 seconds
25 seconds
26 seconds
27 seconds
Seven Seconds over
Fifteen Seconds over
Seven Seconds over
28 seconds
29 seconds
Seven Seconds over
Fifteen Seconds over
30 seconds
31 seconds
32 seconds
33 seconds
34 seconds
Fifteen Seconds over
Seven Seconds over
预期结果是
1 seconds
2 seconds
3 seconds
4 seconds
5 seconds
6 seconds
Seven Seconds over
7 seconds
8 seconds
9 seconds
10 seconds
11 seconds
12 seconds
13 seconds
Seven Seconds over
14 seconds
Fifteen Seconds over
15 seconds
16 seconds
17 seconds
18 seconds
19 seconds
20 seconds
Seven Seconds over
21 seconds
22 seconds
23 seconds
24 seconds
25 seconds
26 seconds
27 seconds
Seven Seconds over
28 seconds
29 seconds
Fifteen Seconds over
30 seconds
31 seconds
32 seconds
33 seconds
34 seconds
Seven Seconds over
注:
当仅调用 SevenSecondMessageThread 和 ContiniousMessageThread 或 FifteenSecondMessageThread 和 ContiniousMessageThread 时,程序运行良好(在预期的行上)。但是当调用所有线程时它会失败。我无法理解为什么会发生这种情况,我该如何避免这种情况?
要获得所需的行为,您可以考虑要同步的对象。在这种情况下,我定义了两个对象(sevenSecond 和 fifteentSecond),并在这两个对象上同步连续线程,以便我们可以准确定义哪个线程开始或停止。
这是您的代码的修改版本,它实现了拥有一个不时被其他两个中断的连续线程的主要思想:
public static void main(String[] args){
Object sevenSecond= new Object();
Object fifteenSecond= new Object();
Message messageObject= new Message();
messageObject.message="seconds";
ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject);
}
static class Message{
String message;
Object sevenLock = new Object();
Object fifteenLock = new Object();
void printMessage(String message) {
try {
for(int i=0; true; i++){
if (i % 7 == 0) {
synchronized (sevenLock) {
sevenLock.notify();
System.out.println(i + " " + message);
sevenLock.wait();
}
}
else if (i % 15 == 0) {
synchronized (fifteenLock) {
fifteenLock.notify();
System.out.println(i + " " + message);
fifteenLock.wait();
}
}
else {
System.out.println(i + " " + message);
System.out.flush();
}
if (i == 50) System.exit(-1); // stops after a few iterations
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
void printMessageFifteen(String message) {
try {
synchronized (fifteenLock) {
System.out.println(message);
fifteenLock.notify();
fifteenLock.wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void printMessageSeven(String message) {
try {
synchronized (sevenLock) {
System.out.println(message);
sevenLock.notify();
sevenLock.wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class ContinousMessageThread extends Thread {
Message messageObject;
ContinousMessageThread(Message messageObject){
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
messageObject.printMessage(this.messageObject.message);
}
}
static class FifteenSecondsMessageThread extends Thread{
Message messageObject;
public FifteenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageFifteen("Fifteen Seconds over");
}
}
}
static class SevenSecondsMessageThread extends Thread {
Message messageObject;
public SevenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageSeven("Seven Seconds over");
}
}
}
请注意,在您的版本中,两个线程(7 和 15)第一次输出它们的消息与连续线程无关(它们可以出现在 0 和 7 或 15 之间的任何地方);从第二个开始,他们就有了想要的行为。
我正在尝试解决下述问题。
编写一个从执行开始就打印消息的程序,另一个线程每第十五条消息打印一条消息。当打印每条消息时,让消息打印线程通知消息打印线程。添加另一个线程,每七条消息打印一条不同的消息,而不修改消息打印线程。
我尝试了以下方法。任何人都可以指导我如何调用程序中的特定线程。
这个class用于
public class Message{
String message;
volatile boolean flag=true;
synchronized void printMessage(String message){
int count=16;
for(int i=0;true;){
i++;
if(i%15==0 || i%7==0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i +" "+message);
notify();
}
}
synchronized void printMessageFifteen(String message){
System.out.println(message);
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
synchronized void printMessageSeven(String message){
System.out.println(message);
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
以连续方式打印消息的线程:
public class ContinousMessageThread extends Thread{
Message messageObject;
ContinousMessageThread(Message messageObject){
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
messageObject.printMessage(this.messageObject.message);
}
}
每十五秒打印一次消息的线程:
public class FifteenSecondsMessageThread extends Thread{
Message messageObject;
public FifteenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageFifteen("Fifteen Seconds over");
}
}
}
每七秒打印一次消息的线程
public class SevenSecondsMessageThread extends Thread {
Message messageObject;
public SevenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageSeven("Seven Seconds over");
}
}
}
Main class 所有线程启动的地方..
public class MainClass {
public static void main(String[] args) {
Object sevenSecond= new Object();
Object fifteenSecond= new Object();
Message messageObject= new Message();
messageObject.message="seconds";
ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject);
}
我得到的输出:
1 seconds
2 seconds
3 seconds
4 seconds
5 seconds
6 seconds
Seven Seconds over
7 seconds
8 seconds
9 seconds
10 seconds
11 seconds
12 seconds
13 seconds
Seven Seconds over
14 seconds
Seven Seconds over
15 seconds
16 seconds
17 seconds
18 seconds
19 seconds
20 seconds
Seven Seconds over
21 seconds
22 seconds
23 seconds
24 seconds
25 seconds
26 seconds
27 seconds
Seven Seconds over
Fifteen Seconds over
Seven Seconds over
28 seconds
29 seconds
Seven Seconds over
Fifteen Seconds over
30 seconds
31 seconds
32 seconds
33 seconds
34 seconds
Fifteen Seconds over
Seven Seconds over
预期结果是
1 seconds
2 seconds
3 seconds
4 seconds
5 seconds
6 seconds
Seven Seconds over
7 seconds
8 seconds
9 seconds
10 seconds
11 seconds
12 seconds
13 seconds
Seven Seconds over
14 seconds
Fifteen Seconds over
15 seconds
16 seconds
17 seconds
18 seconds
19 seconds
20 seconds
Seven Seconds over
21 seconds
22 seconds
23 seconds
24 seconds
25 seconds
26 seconds
27 seconds
Seven Seconds over
28 seconds
29 seconds
Fifteen Seconds over
30 seconds
31 seconds
32 seconds
33 seconds
34 seconds
Seven Seconds over
注:
当仅调用 SevenSecondMessageThread 和 ContiniousMessageThread 或 FifteenSecondMessageThread 和 ContiniousMessageThread 时,程序运行良好(在预期的行上)。但是当调用所有线程时它会失败。我无法理解为什么会发生这种情况,我该如何避免这种情况?
要获得所需的行为,您可以考虑要同步的对象。在这种情况下,我定义了两个对象(sevenSecond 和 fifteentSecond),并在这两个对象上同步连续线程,以便我们可以准确定义哪个线程开始或停止。
这是您的代码的修改版本,它实现了拥有一个不时被其他两个中断的连续线程的主要思想:
public static void main(String[] args){
Object sevenSecond= new Object();
Object fifteenSecond= new Object();
Message messageObject= new Message();
messageObject.message="seconds";
ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject);
}
static class Message{
String message;
Object sevenLock = new Object();
Object fifteenLock = new Object();
void printMessage(String message) {
try {
for(int i=0; true; i++){
if (i % 7 == 0) {
synchronized (sevenLock) {
sevenLock.notify();
System.out.println(i + " " + message);
sevenLock.wait();
}
}
else if (i % 15 == 0) {
synchronized (fifteenLock) {
fifteenLock.notify();
System.out.println(i + " " + message);
fifteenLock.wait();
}
}
else {
System.out.println(i + " " + message);
System.out.flush();
}
if (i == 50) System.exit(-1); // stops after a few iterations
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
void printMessageFifteen(String message) {
try {
synchronized (fifteenLock) {
System.out.println(message);
fifteenLock.notify();
fifteenLock.wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void printMessageSeven(String message) {
try {
synchronized (sevenLock) {
System.out.println(message);
sevenLock.notify();
sevenLock.wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class ContinousMessageThread extends Thread {
Message messageObject;
ContinousMessageThread(Message messageObject){
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
messageObject.printMessage(this.messageObject.message);
}
}
static class FifteenSecondsMessageThread extends Thread{
Message messageObject;
public FifteenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageFifteen("Fifteen Seconds over");
}
}
}
static class SevenSecondsMessageThread extends Thread {
Message messageObject;
public SevenSecondsMessageThread(Message messageObject) {
this.messageObject=messageObject;
new Thread(this,"seconds").start();
}
@Override
public void run() {
while(true){
messageObject.printMessageSeven("Seven Seconds over");
}
}
}
请注意,在您的版本中,两个线程(7 和 15)第一次输出它们的消息与连续线程无关(它们可以出现在 0 和 7 或 15 之间的任何地方);从第二个开始,他们就有了想要的行为。