[英]Multiple Threads For a Java Timer
我正在嘗試編寫一個使用多個線程來創建計時器的簡短Java程序。 當計時器達到7或15秒時,它將打印一條消息。
我需要創建一個共享計數器。 時間打印線程將計數器遞增1並從執行開始每秒打印其值。 消息打印線程每十五秒打印一條消息,另一個消息打印線程每七秒打印一條不同的消息。 需要在不修改時間打印線程的情況下完成這兩個線程。
所有這些線程都需要共享每秒更新的計數器對象。 時間打印線程將通知其他線程每次更新時讀取計數器對象。 然后,每個消息打印線程將讀取計數器值並查看其分配的時間段是否已發生。
輸出應如下所示:
1 2 3 4 5 6
7 second message
7 8 9 10 11 12 13
7 second message
14
15 second message
15 16 17 18 19 20
7 second message
21 22 23 24 . . .
我需要通過為計時器創建一個線程,為7秒消息創建一個線程,為15秒消息創建一個線程來實現這一點。 我在下面構建了這個:
import java.lang.Class;
import java.lang.Object;
class T1 extends Thread {
private Main2 s;
private int t;
T1 (Main2 s) { this.s = s; }
public void run()
{
while(true) {
try { Thread.sleep(1000); }
catch (InterruptedException e) { e.printStackTrace(); }
s.setSharedTime (++t);
System.out.print(t + " ");
}
}
}
class T2 extends Thread {
private Main2 s;
T2 (Main2 s) { this.s = s; }
public void run()
{
while(true) {
int t = s.getSharedTime ();
System.out.println();
System.out.println ("7 second message");
}
}
}
class T3 extends Thread {
private Main2 s;
T3 (Main2 s) { this.s = s; }
public void run()
{
while(true) {
int t = s.getSharedTime ();
System.out.println();
System.out.println ("15 second message");
}
}
}
public class Main2 {
private int time;
private boolean share = true;
public static void main(String[] args) {
Main2 s = new Main2();
new T1 (s).start();
new T2 (s).start();
new T3 (s).start();
}
synchronized void setSharedTime (int s) {
while (!share) {
try { wait (); }
catch (InterruptedException e) {}
}
this.time = s;
if(s % 7 == 0)
share = false;
if(s % 15 == 0)
share = false;
notify ();
}
synchronized int getSharedTime () {
while (share) {
try { wait (); }
catch (InterruptedException e) { }
}
share = true;
notify ();
return time;
}
}
我遇到的問題是我不能在正確的時間拋出7秒和15秒的消息。 如何將這三個線程組合在一起組成一個工作計時器?
在您的代碼中,您使用類T2和T3來打印7秒和15秒的消息,但是沒有標識哪個是哪個並且它們實際上是相同的,保存名稱和打印的字符串。 當調用notify()時,沒有給出鎖定的可指定順序。 來自Javadocs的notify():
喚醒的線程將以通常的方式與可能主動競爭同步此對象的任何其他線程競爭
因此,無論哪種方法(T3的run()或T3的run()獲得鎖定getSharedTime()都將繼續並打印。 請查看此問題和Javadocs以獲取更多相關信息。
這是做同樣事情的類似方法,如果時間是各自類的7或15的倍數,我移動了檢查,並且以不同方式構造了wait()和notify()。 我還將打印與Timer類同步,以便同時(有效地)通知所有wait()。 打印每秒的時間在Timer類中處理,現在設置它的方式將給出你指定的輸出,但切換打印和調用setTime並初始化時間為0將提供更准確的輸出到了現在。
class Timer extends Thread{
private int time = 1;
private boolean setting = false;
public void run(){
while(true){
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(time + " ");
setTime(time + 1);
//Switching the order of these 2 ^^^ statements and initializing time to 0 will give an output that is more accurate to the time.
}
}
public synchronized int getTime(){
while(setting){
try {
wait(); //This will only be run on the off-chance that setTime is being run at the same time.
} catch (InterruptedException e) { }
}
return time;
}
public synchronized void setTime(int t){
setting = true;
this.time = t;
setting = false;
notifyAll();
}
}
class Timer7 extends Thread{
Timer timer;
public Timer7(Timer t){
this.timer = t;
}
public void run(){
synchronized(timer){
while(true){
try {
timer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(timer.getTime() % 7 == 0){
System.out.print("\n7 Second Message\n");
}
}
}
}
}
class Timer15 extends Thread{
Timer timer;
public Timer15(Timer t){
this.timer = t;
}
public void run(){
synchronized(timer){
while(true){
try {
timer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(timer.getTime() % 15 == 0){
System.out.print("\n15 Second Message\n");
}
}
}
}
}
public class Main2 {
public static synchronized void main(String[] args) {
Timer timer = new Timer();
timer.start();
Timer7 t7 = new Timer7(timer);
t7.start();
Timer15 t15 = new Timer15(timer);
t15.start();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.