兩個線程交替打印奇偶

要求描述

兩個線程,其中一個線程打印奇數,另外一個線程打印偶數。兩個線程交替打印,輸入1,2,3,...,100

基本思路

利用通知等待機制,第一個線程打印後,然後喚醒第二個線程,並釋放鎖。第二個線程執行同樣的操作

代碼實現 

package basicKnowledge.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @基本功能:線程交替打印輸出奇偶
 * @program:summary
 * @author:peicc
 * @create:2019-09-26 09:11:15
 **/
public class ThreadPrint {
    static  Object object=new Object();

    public static void main(String[] args) {
        Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    for (int i = 1; i <100 ; i+=2) {
                        System.out.println(Thread.currentThread().getName()+": "+i);
                        object.notify();//喚醒其他線程
                        try {
                            object.wait();
                        }
                        catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        },"打印奇數線程");
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    for (int i = 2; i <=100 ; i+=2) {
                        System.out.println(Thread.currentThread().getName()+": "+i);
                        object.notify();//喚醒其他線程
                        try {
                            object.wait();
                        }
                        catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        },"打印偶數線程");
        thread1.start();
        thread2.start();
    }


}

 輸出結果(後面的省略)

打印奇數線程: 1
打印偶數線程: 2
打印奇數線程: 3
打印偶數線程: 4
打印奇數線程: 5
打印偶數線程: 6
打印奇數線程: 7
打印偶數線程: 8
打印奇數線程: 9
打印偶數線程: 10

上述方法基本解決了我們的需求,但是有個問題,很嚴重,那就是打印結束後打印偶數的線程再次進入了等待狀態,整個程序無法終止。

 代碼升級版

package leetcode;

/**
 * @基本功能:兩個線程交替執行,一個輸出偶數,一個輸出奇數
 * @program:summary
 * @author:peicc
 * @create:2019-07-29 12:56:49
 **/
//線程執行完畢如何終止?
public class ThreadTurn {
     static Object o=new Object();
    static boolean flag=false;//標誌位


    public static void main(String[] args) {
        ThreadTurn threadTurn=new ThreadTurn();
        Thread oddThread=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (threadTurn){
                    for (int i = 1; i <100 ; ) {
                        if(!flag){
                            System.out.println("打印奇數線程"+i);
                            threadTurn.notify();//喚醒等待線程
                            flag=true;
                            i+=2;
                        }else{
                            try {
                                threadTurn.wait();
//                            Thread.sleep(100);
                            }
                            catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }

            }
        },"奇數線程");
        Thread evenThread=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (threadTurn){
                    for (int i = 2; i <= 100; ) {
                        if(flag){
                            System.out.println("打印偶數線程"+i);
                            threadTurn.notify();//喚醒等待線程
                            flag=false;
                            i+=2;
                        }else{
                            try {
                                threadTurn.wait();
//                            Thread.sleep(100);
                            }
                            catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }


                    }
                }
            }
        },"偶數線程");
        evenThread.start();
        oddThread.start();

    }
}

補充練習

兩個線程,其中一個線程打印數字,另外一個線程打印字母。兩個線程交替打印,輸入1,2,a,3,4,b,5,6,c

package basicKnowledge.thread;

/**
 * @基本功能:兩個線程交替執行,一個輸出偶數,一個輸出奇數
 * @program:summary
 * @author:peicc
 * @create:2019-07-29 12:56:49
 **/
//線程執行完畢如何終止?
public class ThreadPrint2 {
     static Object o=new Object();
    static boolean flag=true;//標誌位


    public static void main(String[] args) {
        ThreadPrint2 threadTurn=new ThreadPrint2();
        Thread oddThread=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (threadTurn){
                    int count=0;
                    for (int i = 1; i <=52 ; ) {
                        if(count<2){
                            System.out.println("打印數字線程"+i);
                            threadTurn.notify();//喚醒等待線程
                            count++;
                            i++;
                        }else{
                            try {

                                count=0;
                                threadTurn.wait();
//                            Thread.sleep(100);
                            }
                            catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }

            }
        },"奇數線程");
        Thread evenThread=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (threadTurn){
                    for (int i = 0; i <26; ) {
                        if(flag){
                            System.out.println("打印字母線程"+(char)(i+'a'));
                            threadTurn.notify();//喚醒等待線程
                            flag=false;
                            i++;
                        }else{
                            try {

                                flag=true;
                                threadTurn.wait();
//                            Thread.sleep(100);
                            }
                            catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }


                    }
                }
            }
        },"偶數線程");
        oddThread.start();
        evenThread.start();


    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章