一种简单的三线程交替打印实现(LockSupport实现)

  • Post author:
  • Post category:其他




题目描述

建立三个线程A、B、C,A线程字母A,B线程字母B,C线程字母C,但是要求三个线程同时运行,并且实现交替顺序打印,即按照ABC ABC ABC的顺序打印。



写在前面

这个题算是个臭名昭著的多线程题了,我是没想出来有啥地方需要这样使用多线程。无论是对现代分布式服务端应用,还是客户端Android应用开发都没有这样使用多线程的。保存中间状态对某些

面试官

来说是什么很困难的事情么。服务端操作系统基本都是非实时系统,从根本原理上讲并发保序性就是不保证的。这种强行反工程学的东西只是一个无脑的八股文。

这题有多种变种,无非是添加打印次数之类的截止点,添加计数器即可解决。

网上有使用

Synchroized

关键字和线程的

wait,notify

方法去解决的,写的实在是太复杂了。对现代java(java 8+版本),没有任何理由使用

Synchroized



wait,notify

这些Java 1.0时代的老古董,难以理解又使用不便。

Java 5后Java新增了李大神的并发工具包

java.util.concurrent

,里面有了可重入锁

ReentrantLock

,信号量

Semaphore

等,通过这些工具可以实现三线程交替打印,但是代码复杂度都不低。

实现三个线程交替顺序,核心思路无非是

控制并发度和根据状态转移

。控制并发度,同一时刻只能有一个线程运行,否则多线程并发,系统不保证顺序,就会乱打,或者一个线程打印多次。根据状态转移,也就是根据状态切换到一个状态的线程,必须记录当前状态,然后根据当前状态进行转移,才能实现顺序打印。



使用

ReentrantLock

锁的方案



基本思路

  • 通过锁可以实现

    控制并发度


    通过

    ReentrantLock

    ,我们可以很方便的进行显式的锁操作,即获取锁和释放锁,对于同一个对象锁而言,统一时刻只可能有一个线程拿到了这个锁,此时其他线程通过

    lock.lock()

    来获取对象锁时都会被阻塞,直到这个线程通过

    lock.unlock()

    操作释放这个锁后,其他线程才能拿到这个锁。

  • 按顺序释放锁可以实现

    根据状态转移


    实现交替顺序打印的关键就在于,每个线程按顺序释放锁,并唤醒下个线程。此时已知当前线程的状态,释放锁后需要唤醒下个状态的线程。

    但直接释放锁,唤醒哪个线程可以说是随机的。有没有办法唤醒指定线程呢?

    其实唤醒的线程是不随机的,唤醒的是锁等待队列的头线程,但是哪个线程在排队时成为头线程是随机的,可以认为随机唤醒线程。

    通过并发工具包

    java.util.concurrent

    提供的,配合

    ReentrantLock

    使用的

    Condition

    条件唤醒工具。可以实现唤醒指定线程。



ReentrantLock

搭配使用的

Condition

private Lock lock = new ReentrantLock();  
private Condition condition = lock.newCondition(); 
condition.await();//this.wait();  
condition.signal();//this.notify();  
condition.signalAll();//this.notifyAll();

Condition是被绑定到Lock上的,必须使用lock.newCondition()才能创建一个Condition。从上面的代码可以看出,Synchronized能实现的通信方式,Condition都可以实现,功能类似的代码写在同一行中。但是

Condition

可以实现,指定

Condition

去阻塞线程和唤醒线程,而

wait,notify

是无目标的,所以说当前无任何必要使用

wait,notify

这类老家伙。



代码实现

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

public class MultiThreadPrint {
   

	public void threeThreadAlternatelyPrint(){
   
	
        Lock lock 



版权声明:本文为u011863951原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。