使用多線程循環交替打印字符


使用Condition + Lock 進行實現

private static int count_print = 1;

(1)此處只能用static,來實現每打印一個字符,下一個字符長度加一,static是使該變量只有一個副本,任何改變都是對這個副本的內容做操作
(2)若是想實現每打印一組,下一組字符每個字符長度加一,就不使用static,因為三個線程,有三個線程實例即ThreadTest實例,若不設置成靜態,
那么每次改變的是對象內部的count_print屬性,所以其他兩個線程是不可見的



 程序一:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest implements Runnable {

    public static final int COUNT = 5;
    private final ReentrantLock reentrantLock;
    private final Condition thisCondition;
    private final Condition nextCondition;
    private final char printChar;

    // 此處只能用static,來實現每打印一個字符,下一個字符長度加一,static是使該變量只有一個副本,任何改變都是對這個副本的內容做操作
    // 若是想實現每打印一組,下一組字符每個字符長度加一,就不使用static,因為三個線程,有三個線程實例即ThreadTest實例,若不設置成靜態,
    // 那么每次改變的是對象內部的count_print屬性,所以其他兩個線程是不可見的

    private static int count_print = 1;

    public ThreadTest(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar) {
        this.reentrantLock = reentrantLock;
        this.thisCondition = thisCondition;
        this.nextCondition = nextCondition;
        this.printChar = printChar;

    }

    @Override
    public void run() {
        reentrantLock.lock();

        try {
            for (int i = 0; i < COUNT; i++) {

                for (int j = 0; j < count_print; j++) {
                    System.out.print(printChar);
                }
                count_print += 1;
                nextCondition.signal();

                // 不是最后一次則通過thisCondtion等待被喚醒
                // 必須要加判斷,不然雖然能夠打印5次,但5次后就會直接死鎖

                if (i < COUNT - 1) {
                    try {
                        // 使用Condition的await()方法將當前線程放入等待隊列,並使其能在下一次被喚醒繼續往下執行,而不是從頭開始執行
                        thisCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            reentrantLock.unlock();
        }
    }

    public static void main(String args[]) throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        Thread threadA = new Thread(new ThreadTest(lock, conditionA, conditionB, 'A'));
        Thread threadB = new Thread(new ThreadTest(lock, conditionB, conditionC, 'B'));
        Thread threadC = new Thread(new ThreadTest(lock, conditionC, conditionA, 'C'));

        threadA.start();
        Thread.sleep(100);
        threadB.start();
        Thread.sleep(100);
        threadC.start();
    }
}

(1)//此處只能用static,來實現每打印一個字符,下一個字符長度加一,static是使該變量只有一個副本,任何改變都是對這個副本的內容做操作

private static int count_print = 1;

輸出結果:

(2)若是想實現每打印一組,下一組字符每個字符長度加一,就不使用static,因為三個線程,有三個線程實例即ThreadTest實例,若不設置成靜態,
那么每次改變的是對象內部的count_print屬性,所以其他兩個線程是不可見的,可能不太好理解,將ThreadTest類單獨寫出來,在利用import引入進另一個有主方法的類就比較直觀了

private int count_print = 1;

輸出結果:

 

 程序二

//只是循環打印每組字符,不考慮字符增長

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest implements Runnable {

    public static final int COUNT = 5;
    private final ReentrantLock reentrantLock;
    private final Condition thisCondition;
    private final Condition nextCondition;
    private final char printChar;

    private static int count_print = 1;

    public ThreadTest(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar) {

        this.reentrantLock = reentrantLock;
        this.thisCondition = thisCondition;
        this.nextCondition = nextCondition;
        this.printChar = printChar;

    }

    @Override
    public void run() {
        reentrantLock.lock();

        try {
            for (int i = 0; i < COUNT; i++) {
                System.out.print(printChar);
                nextCondition.signal();
                if (i < COUNT - 1) {
                    try {
                        // 使用Condition的await()方法將當前線程放入等待隊列,並使其能在下一次被喚醒繼續往下執行,而不是從頭開始執行
                        thisCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            reentrantLock.unlock();
        }
    }

    public static void main(String args[]) throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        Thread threadA = new Thread(new ThreadTest(lock, conditionA, conditionB, 'A'));
        Thread threadB = new Thread(new ThreadTest(lock, conditionB, conditionC, 'B'));
        Thread threadC = new Thread(new ThreadTest(lock, conditionC, conditionA, 'C'));

        threadA.start();
        Thread.sleep(100);
        threadB.start();
        Thread.sleep(100);
        threadC.start();
    }
}

 運行結果為:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM