package com.soft.transform.service.thread;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.sunline.common.config.DefaultConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.TimeUnit;
/**
* Created by CaiJianbo on 2016/6/18 13:58.
* sunline
*/
@Component
public class MarketJobDaemon extends Thread {
private static Logger logger = LoggerFactory.getLogger(MarketJobDaemon.class);
private Vector<MarketJobInfo> workers = new Vector<>();
private Vector<MarketJobInfo> updatedWorkers = new Vector<>();
@Autowired
private PhTransCodingThread phTransCodingThread;
@Autowired
private PhTsPersistenceThread phTsPersistenceThread;
@Autowired
private PhTsHisPersistenceThread phTsHisPersistenceThread;
@Autowired
private TsMinutePersistenceThread tsMinutePersistenceThread;
@Autowired
private TsFiveMinutePersistenceThread tsFiveMinutePersistenceThread;
@Resource
DefaultConfig defaultConfig;
private long lastLogTime;
@PostConstruct
private void initJobs() {
workers.add(new MarketJobInfo().setJob(phTransCodingThread)
.setJobName(phTransCodingThread.getClass().getSimpleName()));
workers.add(new MarketJobInfo().setJob(phTsPersistenceThread)
.setJobName(phTsPersistenceThread.getClass().getSimpleName()));
workers.add(new MarketJobInfo().setJob(phTsHisPersistenceThread)
.setJobName(phTsHisPersistenceThread.getClass().getSimpleName()));
workers.add(new MarketJobInfo().setJob(tsMinutePersistenceThread)
.setJobName(tsMinutePersistenceThread.getClass().getSimpleName()));
workers.add(new MarketJobInfo().setJob(tsFiveMinutePersistenceThread)
.setJobName(tsFiveMinutePersistenceThread.getClass().getSimpleName()));
}
@Override
public void run() {
if (CollectionUtils.isNotEmpty(workers)) {
while (true) {
try {
long dateTime = new Date().getTime();
Iterator<MarketJobInfo> iterator = workers.iterator();
MarketJobInfo jobInfo;
BaseMarketThread job;
Thread workThread;
while (iterator.hasNext()) {
jobInfo = iterator.next();
workThread = jobInfo.getWorkThread();
job = jobInfo.getJob();
synchronized (jobInfo) {
if (job.isRunnable(dateTime)) {
if (!workThread.isAlive()) {
if (workThread.getState() == State.NEW) {
jobInfo.startJob(Thread.currentThread());
logger.info("启动线程:" + jobInfo.getJobName());
} else if (workThread.getState() == State.WAITING) {
synchronized (workThread) {
workThread.notify();
}
logger.info("启动线程:" + jobInfo.getJobName());
} else if (workThread.getState() == State.TERMINATED) {
workThread = jobInfo.updateWorkThread();
jobInfo.startJob(Thread.currentThread());
iterator.remove();
updatedWorkers.add(jobInfo);
logger.info("启动线程:" + jobInfo.getJobName());
}
}
} else {
if (workThread.isAlive()) {
job.isInterrupt = true;
synchronized (workThread) {
workThread.interrupt();
}
logger.info("关闭线程:" + jobInfo.getJobName());
}
}
}
}
if (Math.abs(dateTime - lastLogTime) / (1000 * 60) >= 1) {
new Thread(new Runnable() {
@Override
public void run() {
logWorkState();
}
}).start();
}
if (CollectionUtils.isNotEmpty(updatedWorkers)) {
workers.addAll(updatedWorkers);
updatedWorkers.clear();
}
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
logger.error("线程异常。", e);
}
}
}
}
public void logWorkState() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("线程状态:{");
for (MarketJobInfo jobInfo : workers) {
stringBuilder.append("\"").append(jobInfo.getJobName()).append("\"").append(":").append("\"")
.append(jobInfo.getWorkThread().getState()).append("\"").append(",");
}
stringBuilder.append("}");
logger.info(stringBuilder.toString());
lastLogTime = new Date().getTime();
}
public synchronized void StopOtherThread(Set<String> exceptJob) {
if (exceptJob == null) {
exceptJob = new HashSet<>();
}
Thread thread;
for (MarketJobInfo worker : workers) {
if (!exceptJob.contains(worker.getJobName())) {
thread = worker.getWorkThread();
if (!thread.isInterrupted()) {
worker.getJob().isInterrupt = true;
thread.interrupt();
}
}
}
}
}