【并发编程】- Semaphore多线程处理任务

102 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

@Slf4j
public class SemaphoreService {
    private Semaphore semaphore = new Semaphore(1);

    public void testSemaphore(){
        if(semaphore.tryAcquire()){
            log.info("线程名{}获取许可",Thread.currentThread().getName());
            for (int i = 0; i < Integer.MAX_VALUE/50; i++) {
                String msg = new String();
                Math.random();
            }
            semaphore.release();
        }else{
            log.info("线程名{}未能获取许可",Thread.currentThread().getName());
        }
    }
}

运行类代码如下:

public class Test{

    public static void main(String[] args){
        SemaphoreService service = new SemaphoreService();
        ThreadA threadA = new ThreadA(service);
        threadA.setName("A");
        ThreadB threadB = new ThreadB(service);
        threadB.setName("B");
        ThreadC threadC = new ThreadC(service);
        threadC.setName("C");
        threadA.start();
        threadB.start();
        threadC.start();
     }
}

程序结果如下:

15:36:52.429 [B] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名B未能获取许可
15:36:52.429 [A] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名A获取许可
15:36:52.429 [C] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名C未能获取许可
多进路-多处理-多出路

允许多个线程同时处理任务,也就是每个线程都在处理自己的任务。

多线程执行各自任务具体代码如下:

@Slf4j
public class MoreThreadService {
    private Semaphore semaphore = new Semaphore(3);

    public void sayHello(){
        try {
            semaphore.acquire();
            log.info("线程名:{} 准备",Thread.currentThread().getName());
            log.info("开始打招呼 :{}",System.currentTimeMillis());
            for (int i = 0; i < 3 ; i++) {
                log.info("线程名:{},打印的值:{}",Thread.currentThread().getName(),i+1);
            }
            log.info("结束打招呼 :{}",System.currentTimeMillis());
            semaphore.release();
            log.info("线程名:{} 结束",Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

单线程实现代码如下:

public class FirstThread implements Runnable {

    private MoreThreadService service;

    public FirstThread(MoreThreadService moreThreadService){
        super();
        this.service=moreThreadService;
    }

    @Override
    public void run() {
        service.sayHello();
    }
}

运行类代码如下:

public class MoreThreadTest {

    public static void main(String[] args) {
        MoreThreadService moreThreadService = new MoreThreadService();
        FirstThread[] threads = new FirstThread[3];
        for (int i = 0; i <threads.length ; i++) {
            threads[i] = new FirstThread(moreThreadService);
            new Thread(threads[i]).start();
        }
    }
}

程序运行结果如下:

15:53:28.610 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-0 准备
15:53:28.623 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 开始打招呼 :1649404408623
15:53:28.623 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-0,打印的值:1
15:53:28.623 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-0,打印的值:2
15:53:28.610 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-2 准备
15:53:28.623 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-0,打印的值:3
15:53:28.624 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 结束打招呼 :1649404408624
15:53:28.624 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-0 结束
15:53:28.610 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-1 准备
15:53:28.625 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 开始打招呼 :1649404408625
15:53:28.624 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 开始打招呼 :1649404408624
15:53:28.625 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-2,打印的值:1
15:53:28.625 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-1,打印的值:1
15:53:28.625 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-2,打印的值:2
15:53:28.625 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-1,打印的值:2
15:53:28.625 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-2,打印的值:3
15:53:28.625 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-1,打印的值:3
15:53:28.625 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 结束打招呼 :1649404408625
15:53:28.625 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 结束打招呼 :1649404408625
15:53:28.625 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-1 结束
15:53:28.625 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.MoreThreadService - 线程名:Thread-2 结束

有结果可见,多个线程同时进入,而多个线程又几乎同时执行完毕,并且各线程打印循环内容是乱序。