一起做面試題--Java多線程交替列印__Java

來源:互聯網
上載者:User

這道面試題的內容是,要求兩個線程交替列印,列印出"12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z"。

一個線程只列印數字,另一個線程只列印字母,列印數位線程列印兩個數字後,列印字母的線程列印一個字母,然後交替下去直到列印完所有字母,數字列印到52即可。

這個的思路就是線程交替運行,交替啟動並執行關鍵在於,一個線程執行完一個周期,立即掛起,同時通知另一個線程執行,另一個線程執行完,同樣立即掛起,再通知之前的線程。兩個線程都需要掛起和獲得通知,但是兩個線程是互相獨立的,所以用對象監視器鎖是不合適的,因為對象監視器的掛起和通知是無差異的,有可能會在掛起後將本線程立即啟用,而需要被啟用的線程仍在被掛起。。。所以這裡要用ReentrantLock和兩個Condition,不多說了看代碼。

//線程A負責列印數字

class ThreadA extends Thread{
//一個鎖和兩個Condition

        private Lock lock;
private Condition c1;
private Condition c2;

//構造方法注入這些引用
public ThreadA(Lock lock,Condition c1,Condition c2){
this.lock=lock;
this.c1=c1;
this.c2=c2;
}
//線程開始
public void run(){
try {
lock.lock();//加鎖

                        //迴圈52次
for(int i=1;i<=52;i++){
//i為奇數時可以列印,列印兩次

                                     if(i%2!=0){
System.out.print(i+""+(i+1));
c2.signal();//通知c2這個condition開始運行
}else{
c1.await();//i為偶數時c1掛起
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
}


class ThreadB extends Thread{
private Lock lock;
private Condition c1;
private Condition c2;

public ThreadB(Lock lock,Condition c1,Condition c2){
this.lock=lock;
this.c1=c1;
this.c2=c2;
}

public void run(){
  try {
lock.lock();
  char c='A';//定義char變數作為列印變數
  for(int i=0;i<51;i++){//迴圈51次,因為遍曆26個字母並且每個字母之間插入兩個數位話,需要迴圈51次,我是調試出來的,最初我也不知道需要51次。。。這裡並不把char作為迴圈變數因為涉及到的是奇數次迴圈時不列印,所以char如果作為迴圈變數會跳過奇數次迴圈,會丟失列印。
  if(i%2==0){//偶數次迴圈時列印c並自增,通知c1這個condition可以運行。
  System.out.print(c++);
  c1.signal();
  }else{//迴圈奇數次時,c2這個condition掛起。
  c2.await();
  }
  }
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
}


這是兩個線程類,看main方法。

public static void main(String[] args) throws InterruptedException {
Lock lock=new ReentrantLock();
Condition c1=lock.newCondition();
Condition c2=lock.newCondition();
ThreadA a=new ThreadA(lock,c1,c2);
ThreadB b=new ThreadB(lock,c1,c2);
a.start();
Thread.sleep(50);
b.start();
}

這個沒什麼難的,線程A先啟動,然後線程B再啟動。結果正確。

我寫的不一定是最好的,肯定有更優的解法,歡迎大家指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.