串行线程封闭(Serial Thread Confinement)

九、串行线程封闭(Serial Thread Confinement)
1、核心思想
通过将多个并发的任务存入队列实现任务的串行化,并为这些串行化的任务创建唯一的一个工作线程进行处理。
本质:使用一个开销更小的锁(队列锁)去替代另一个可能开销更大的锁(非线程安全对象引用的锁)
2、适用场景
a、需要使用非线程安全对象,但又不希望引入锁。
b、任务的执行涉及I/O操作,不希望过多的I/O线程增加上下文切换
3、是生产消费者模式的一个例子。

/**
 * 对任务处理的抽象
 * @author huzhiqiang
 *
 * @param <T>
 *      任务的类型
 * @param <V>
 *      任务处理结果的类型
 */
public interface TaskProcssor<T, V> {
    V doProcess(T task) throws Exception;
}

public class TerminatableWorkerThread<T, V> extends AbstractTerminatableThread {
    private final BlockingQueue<Runnable> workQueue;

    //负责正真执行任务的对象
    private final TaskProcssor<T, V> taskProcssor;

    public TerminatableWorkerThread(BlockingQueue<Runnable> workQueue, TaskProcssor<T, V> taskProcssor) {
        super();
        this.workQueue = workQueue;
        this.taskProcssor = taskProcssor;
    }

    public Future<V> submit(final T task) throws InterruptedException{
        Callable<V> callable = new Callable<V>() {
            @Override
            public V call() throws Exception {
                return taskProcssor.doProcess(task);
            }
        };

        FutureTask<V> ft = new FutureTask<V>(callable);
        workQueue.put(ft);

        terminationToken.reservations.incrementAndGet();
        return ft;
    }

    @Override
    protected void doRun() throws Exception {
        Runnable ft = workQueue.take();

        try {
            ft.run();
        } finally{
            terminationToken.reservations.decrementAndGet();
        }
    }
}

public abstract class AbstractSerializer<T, V> {
    private final TerminatableWorkerThread<T, V> workerThread;

    public AbstractSerializer(BlockingQueue<Runnable> workQueue, TaskProcssor<T, V> taskProcssor) {
        super();
        this.workerThread = new TerminatableWorkerThread<>(workQueue, taskProcssor);
    }

    /**
     * 留给子类实现。用于根据指定参数生成相应的任务实例
     * @param params
     * @return
     */
    public abstract T makeTask(Object... params);

    /**
     * 对外暴露的方法
     * @param params
     * @return
     * @throws InterruptedException
     */
    public Future<V> service(Object... params) throws InterruptedException{
        T task = makeTask(params);
        Future<V> resultPromise = workerThread.submit(task);
        return resultPromise;
    }

    public void init(){
        workerThread.start();
    }

    public void shutdown(){
        workerThread.terminate();
    }
}

public class Main {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        SomeService ss = new SomeService();
        ss.init();

        Future<String> result = ss.doSomething("serial Thread confinement", 1);

        Thread.sleep(50);
        System.out.println(result.get());

        ss.shutdown();
    }

    private static class Task{
        private final int id;
        private final String message;

        public Task(int id, String message) {
            this.id = id;
            this.message = message;
        }
    }

    private static class SomeService extends AbstractSerializer<Task, String>{

        public SomeService(){
            super(new ArrayBlockingQueue<>(100), new TaskProcssor<Task, String>() {
                @Override
                public String doProcess(Task task) throws Exception {
                    System.out.println("[" + task.id + "]: " + task.message);
                    return task.message + " accepted.";
                }
            });
        }

        @Override
        public Task makeTask(Object... params) {
            String message = (String) params[0];
            int id = (int) params[1];
            return new Task(id, message);
        }

        public Future<String> doSomething(String message, int id) throws InterruptedException{
            Future<String> result = null;
            result = service(message, id);
            return result;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值