package cn.mutils.core.concurrent; import java.util.LinkedList; import java.util.List; /** * Concurrent Worker */ @SuppressWarnings({"deprecation", "UnusedAssignment", "SimplifiableIfStatement", "unused"}) public abstract class Worker<JOB> implements IWoker<JOB> { /** * Jobs to work */ protected List<JOB> mJobs; /** * Jobs to work for concurrent threads access */ protected List<JOB> mWorkingJobs; /** * Concurrent threads */ protected List<Thread> mConcurrentWorkers; /** * Whether worker is started */ protected boolean mStarted; /** * Whether worker is prepared to work */ protected boolean mPrepared; public Worker() { } public Worker(List<JOB> jobs) { this.delegate(jobs); } @Override public synchronized void delegate(List<JOB> jobs) { if (mStarted) { return; } mJobs = jobs; } @Override public synchronized boolean start() { if (mStarted) { return false; } int workerCount = getConcurrentCount(); if (workerCount < 1) { throw new UnsupportedOperationException(); } mStarted = true; mConcurrentWorkers = new LinkedList<Thread>(); for (int i = 0; i < workerCount; i++) { WorkThread worker = new WorkThread(); mConcurrentWorkers.add(worker); worker.start(); } return true; } @Override public synchronized boolean stop() { if (!mStarted) { return false; } if (mConcurrentWorkers != null) { for (Thread worker : mConcurrentWorkers) { if (worker.isAlive()) { worker.stop(); } } mConcurrentWorkers.clear(); mConcurrentWorkers = null; } mJobs = null; return true; } @Override public int getConcurrentCount() { int cores = Runtime.getRuntime().availableProcessors(); return cores > 1 ? cores - 1 : cores; } @Override public double getProgress() { try { double progress = 1 - (mWorkingJobs.size() + 1.0) / mJobs.size(); progress = progress > 1 ? 1 : progress; progress = progress < 0 ? 0 : progress; return progress; } catch (Exception e) { return mStarted ? 1 : 0; } } @Override public synchronized boolean prepare(List<JOB> jobs) { if (mPrepared || !mConcurrentWorkers.contains(Thread.currentThread())) { return false; } mPrepared = true; mWorkingJobs = new LinkedList<JOB>(); if (jobs != null) { mWorkingJobs.addAll(jobs); } return true; } @Override public synchronized int getId(JOB job) { try { return mJobs.indexOf(job); } catch (Exception e) { return -1; } } class WorkThread extends Thread { @Override public void run() { prepare(mJobs); while (true) { JOB job = null; try { synchronized (Worker.this) { job = mWorkingJobs.remove(0); } } catch (Exception e) { break; } try { work(job); } catch (Exception e) { // Unknown Exception } yield(); } synchronized (Worker.this) { mConcurrentWorkers.remove(this); if (mConcurrentWorkers.size() == 0) { done(); mConcurrentWorkers = null; mJobs = null; } } } @Override public boolean equals(Object o) { if (this == o) { return true; } else { if (o != null && (o instanceof Thread)) { return this.getId() == ((Thread) o).getId(); } else { return false; } } } } }