Java 在多线程当中顺序执行程序

题目:

有三个线程,每个线程,打印A、B、C 的操作,现要求同时执行三个线程,要求打印的顺序为A、B、C 不乱序,重复10次。


思路:

        在这里实际上是要进行线程的顺序操作。一般来说,线程的操作是无序的,随机发生的,若只是单纯的让这些线程发生的话,那么ABC的打印顺序自然就是无序的。那么,现在的问题就在于要约束线程的执行。

        在我的想法当中,约束线程的执行,那么只需要将不需要运行的线程暂时挂起,让需要运行的线程继续运行就可以达到这种效果了。

        那么,在这里,我就将引入一个信号量(Semaphore),利用信号量去控制线程的进行。

        或许有的朋友会问信号量是什么,信号量其实就相当于一个大门(临界区)的门锁,信号量则是限制了进入门(临界区)的人数(线程数)。举个例子,当你的信号量为10的时候,若有11个线程申请进入,那么当进入了10个线程之后,临界区的入口则会被挂起,那么,最后的那个线程只能等待,直到已经进入了门(临界区)内的代码执行完毕,释放了信号量才可以进入。

        那么,控制线程的顺序执行的原理也是这样的。

        当你要打印字母A的时候,那么打印字母BC的线程自然需要挂起,当字母A打印完毕之后,再释放了字母B的信号量,自然就可以打印字母B了,同样,字母C也可以用同样的方法去打印。以此类推,字母ABC就可以按顺序全部打印出来了。


实现

    之后则是这个思路的实现方式。

    首先,要有三个信号量分别去约束ABC的打印的线程    

        //信号量只有1则代表只有1个线程可以访问临界区
        Semaphore semaphoreA = new Semaphore(1);
        Semaphore semaphoreB = new Semaphore(1);
        Semaphore semaphoreC = new Semaphore(1);

        semaphoreB.acquire();
        semaphoreC.acquire();

当然,因为必须要打印字母A为先,所以,一开始就要挂起字母BC的线程

然后则是线程的编写

public class PrintThread extends Thread  {

    private String word;

    private Semaphore thisLock, nextLock;

    public PrintThread(String word,Semaphore thisRun,Semaphore nextRun){
        this.word = word;

        thisLock = thisRun;
        nextLock = nextRun;
    }

    @Override
    public void run() {

        try {
            for(int i = 0;i <10;i++) {
                thisLock.acquire();
                System.out.print(word);
                nextLock.release();
            }


        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

当要打印当前字母的时候,首先先将这段代码进入了临界区,这意味着这次打印之后这段代码将会被挂起,直到信号量被释放为止(因为信号量的数量设置为1),然后,在打印之后,释放下一个将要执行的代码的信号量,这意味着打印下一个字母的代码将会被执行,以此类推,就可以一直按顺序执行代码了。

public class Main {

    public static void main(String[] args) throws InterruptedException {
        // write your code here

        //信号量只有1则代表只有1个线程可以访问临界区
        Semaphore semaphoreA = new Semaphore(1);
        Semaphore semaphoreB = new Semaphore(1);
        Semaphore semaphoreC = new Semaphore(1);

        semaphoreB.acquire();
        semaphoreC.acquire();

        PrintThread threadA = new PrintThread("A", semaphoreA, semaphoreB);  //锁住当前线程,打开下一个线程的锁
        PrintThread threadB = new PrintThread("B", semaphoreB, semaphoreC);
        PrintThread threadC = new PrintThread("C", semaphoreC, semaphoreA);

        threadA.start();
        threadB.start();
        threadC.start();

    }
}

结果:

猜你喜欢

转载自blog.csdn.net/a591243801/article/details/79541604