/// <summary> /// Create a new thread pool. number of threads in the pool can be smaller /// than maximum number of simultaneously placed job. Burst of new jobs can be /// served by small number of threads /// </summary> /// <param name="name"> /// A <see cref="System.String"/> /// Name of the thread pool as it appears in debug reports /// </param> /// <param name="threads"> /// A <see cref="System.Int32"/> /// Number of service threads /// </param> /// <param name="jobs"> /// A <see cref="System.Int32"/> /// Maximum number of pending (yet to be served) jobs. The maximum number of jobs /// can larger than number of service threads /// </param> /// <param name="priority"> /// A <see cref="Thread.Priority"/> /// Priority of the service threads /// </param> public ThreadPool(string name, int threads, int jobs, System.Threading.ThreadPriority priority) { this.Name = name; this.Threads = threads; this.Jobs = jobs; MinThreadsFree = threads; countStart = 0; countDone = 0; countMaxJobs = 0; countRunningThreads = 0; jobThreads = new Stack <JobThread>(threads); runningThreads = new List <JobThread>(threads); for (int i = 0; i < threads; i++) { JobThread jobThread = new JobThread(this, priority); jobThreads.Push(jobThread); } pendingJobs = new Queue <JobParams>(this.Jobs); freeJobs = new Stack <JobParams>(this.Jobs); for (int i = 0; i < this.Jobs; i++) { JobParams jobParams = new JobParams(); freeJobs.Push(jobParams); } // add myself to the list of created thread pools Resources.ThreadPools.Add(this); }
/// <summary> /// 获取JobThread /// </summary> /// <returns>true表示新创建的线程,否则表示原有的</returns> public bool GetJobThread(TriggerParam triggerParam, out JobThread jobThread) { lock (_syncObject) { if (_jobThreads.TryGetValue(triggerParam.jobId, out jobThread)) { if (jobThread.Stopped) { jobThread = CreateJobThread(triggerParam.jobId); return(true); } if (jobThread.IsRunningOrHasQueue() && Constants.ExecutorBlockStrategy.COVER_EARLY == triggerParam.executorBlockStrategy) { jobThread.Interrupt("block strategy effect:" + triggerParam.executorBlockStrategy); jobThread = CreateJobThread(triggerParam.jobId); return(true); } return(false); } else { jobThread = CreateJobThread(triggerParam.jobId); return(true); } } }
/// <summary> /// return the service thread to the stack of free threads /// this method is called from the service thread /// </summary> protected void JobThreadDone(JobThread jobThread) { lock (jobThreads) { countDone++; runningThreads.Remove(jobThread); jobThreads.Push(jobThread); } }
private ReturnT IdleBeat(int jobId) { JobThread jobThread = _jobThreadFactory.FindJobThread(jobId); if (jobThread != null && jobThread.IsRunningOrHasQueue()) { return(ReturnT.CreateFailedResult("job thread is running or has trigger queue.")); } return(ReturnT.SUCCESS); }
/// <inheritdoc /> protected override void StopFunction() { _stop.Set(); JobThread.Join(); foreach (var worker in _workers) { worker.Join(); } _listener.Stop(); }
public ReturnT <String> kill(int jobId) { // kill handlerThread, and create new one JobThread jobThread = XxlJobExecutor.loadJobThread(jobId); if (jobThread != null) { XxlJobExecutor.removeJobThread(jobId, "人工手动终止"); return(ReturnT <string> .SUCCESS); } return(new ReturnT <String>(ReturnT <string> .SUCCESS_CODE, "job thread aleady killed.")); }
public void Start() { if (jobs_started) { return; } jobs_started = true; for (int i = 0; i < threads.Length; i++) { threads[i] = new JobThread(); threads[i].Start(); } }
/// <summary> /// start a service thread if there are free service threads /// </summary> protected void RefreshQueue() { bool shouldSpawnJob; JobThread jobThread = default(JobThread); do { shouldSpawnJob = (countRunningThreads == 0); // there are some running threads // I can get out - one of the running threads will serve // queue of pending jobs if (!shouldSpawnJob) { break; } lock (jobThreads) { if (jobThreads.Count > 0) { jobThread = jobThreads.Pop(); runningThreads.Add(jobThread); MinThreadsFree = Math.Min(MinThreadsFree, jobThreads.Count); countStart++; } } // there is a free thread to serve the job // start the thread and get out if (jobThread != default(JobThread)) { jobThread.Start(); break; } lock (this) { countFailedRefreshQueue++; } // i have to wait. there are no available threads and no thread is // running. should not be too long before a thread finishes Thread.Sleep(1); }while (true); }
public ReturnT <String> idleBeat(int jobId) { // isRunningOrHasQueue bool isRunningOrHasQueue = false; JobThread jobThread = XxlJobExecutor.loadJobThread(jobId); if (jobThread != null && jobThread.isRunningOrHasQueue()) { isRunningOrHasQueue = true; } if (isRunningOrHasQueue) { return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "job thread is running or has trigger queue.")); } return(ReturnT <string> .SUCCESS); }
private void OnProcessJobs() { SaveConfig(); if (_jobs.Count == 0) { LogWarning("No job in the list."); return; } if (!IsMEncoderPathValid(Config.MEncoderFilePath)) { return; } if (_jobs.Count != _jobsListView.Items.Count) { LogError("The GUI and application job list count don't match. You should restart the application."); return; } Gui_OnJobStart(); _jobsListView.Background = _jobsListViewBackground; if (JobThread != null) { JobThread.Join(); } // Create a copy to be used only by the thread. var data = new JobsProcessThreadData(); // ... JobThread = new Thread(JobsThread); JobThread.Start(data); }
private void AddJobs(List <string> filePaths, List <string> folderPaths) { if (filePaths.Count == 0 && folderPaths.Count == 0) { return; } Gui_OnJobStart(); _jobsListView.Background = _jobsListViewBackground; if (JobThread != null) { JobThread.Join(); } // Create a copy to be used only by the thread. var data = new JobAddThreadData(); data.FilePaths.AddRange(filePaths); data.FolderPaths.AddRange(folderPaths); JobThread = new Thread(JobAddThread); JobThread.Start(data); }
public ReturnT <String> run(TriggerParam triggerParam) { //// load old:jobHandler + jobThread JobThread jobThread = XxlJobExecutor.loadJobThread(triggerParam.jobId); IJobHandler jobHandler = jobThread != null?jobThread.getHandler() : null; String removeOldReason = null; switch (triggerParam.glueType) { case "BEAN": { IJobHandler newJobHandler = XxlJobExecutor.loadJobHandler(triggerParam.executorHandler); // valid old jobThread if (jobThread != null && jobHandler != newJobHandler) { // change handler, need kill old thread removeOldReason = "更换JobHandler或更换任务模式,终止旧任务线程"; jobThread = null; jobHandler = null; } // valid handler if (jobHandler == null) { jobHandler = newJobHandler; if (jobHandler == null) { return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "job handler [" + triggerParam.executorHandler + "] not found.")); } } break; } default: { return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "glueType[" + triggerParam.glueType + "] is not valid.")); } } //// executor block strategy if (jobThread != null) { ExecutorBlockStrategyEnum blockStrategy = (ExecutorBlockStrategyEnum)Enum.Parse(typeof(ExecutorBlockStrategyEnum), triggerParam.executorBlockStrategy); if (ExecutorBlockStrategyEnum.DISCARD_LATER == blockStrategy) { // discard when running if (jobThread.isRunningOrHasQueue()) { return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "阻塞处理策略-生效:" + ExecutorBlockStrategyEnum.DISCARD_LATER.ToString())); } } else if (ExecutorBlockStrategyEnum.COVER_EARLY == blockStrategy) { // kill running jobThread if (jobThread.isRunningOrHasQueue()) { removeOldReason = "阻塞处理策略-生效:" + ExecutorBlockStrategyEnum.COVER_EARLY.ToString(); jobThread = null; } } else { // just queue trigger } } // replace thread (new or exists invalid) if (jobThread == null) { jobThread = XxlJobExecutor.registJobThread(triggerParam.jobId, jobHandler, removeOldReason); } // push data to queue ReturnT <String> pushResult = jobThread.pushTriggerQueue(triggerParam); return(pushResult); }