- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个简单的视频操纵器,因此我需要每秒几次启动一个新线程(当前实现 Runnable)来处理当前帧,但我无法保证每个线程需要多长时间才能完成并且因此,我想将可以同时运行的线程数量限制为计算机上的处理器数量:
Runtime runtime = Runtime.getRuntime();
int nP = runtime.availableProcessors();
但我需要保证创建的所有线程都按顺序运行,因此不会丢失任何帧。
我还想向用户展示完成处理需要多长时间,具体取决于取消作业时剩余运行的线程数,这样他们就不会得到没有预告片的视频文件。
使用 futureTask、Exector 或 ExecutorService 的任意组合可以实现这一点吗?
谢谢。
编辑:
大家好,抱歉,是的,措辞相当糟糕。所以我实际上想做的是获取帧,执行一些图像处理,然后将编辑后的素材保存回新文件。目前,我在播放期间执行此操作,因此当计时器调用时,会对每个帧进行操作,然后计时器启动一个线程来尽快处理图像,但根据这次执行的操作数量会有所不同。
然后我想确保,如果处理时间比间隔长,则仅使用最大有效数量的线程进行处理,并且在达到此限制后创建的任何线程仍会得到处理而不是被删除或垃圾收集。
读完前 3 条评论后,我发现这可能是一种效率较低的方法,我想只有一个线程来保持 UI 响应会起作用,但我不确定如何继续将图像添加到线程在不使用巨大列表的情况下进行处理。我假设它会是这样的:
在主类中:
Timer actionPerformed {
List.add(decodedImage);
}
在可运行类中:
run() {
while( timer.isRunning() ) {
if( runCount >= list.size()-1 ) {
try {
Thread.sleep(500);
} catch() {
/* Catchy stuff */
}
} else {
BufferedImage toProcess = list.get(runCount);
/* Do Processing here */
writeImageToStream();
list.remove(runCount);
runCount++;
}
}
}
这是正确的吗?
编辑2:
这就是我到目前为止所拥有的:
public class timerEncode {
private long startTime;
ActionListener goAction = new ActionListener() {
public void actionPerformed( ActionEvent evt ) {
BufferedImage decoded = getNextImage();
long write_time = System.nanoTime();
new doImages(decoded, write_time).run();
}
};
Timer goTimer = new Timer(40,goAction);
private BufferedImage getNextImage() {
/* Does inconsequential stuff to retrieve image from the stream*/
}
private void recBtnActionPerformed(java.awt.event.ActionEvent evt) {
startTime = System.nanoTime();
goTimer.start();
}
private class doImages implements Runnable {
final BufferedImage image;
final long write_time;
public doImages(BufferedImage image, long write_time) {
this.image = image;
this.write_time = write_time;
}
public void run() {
BufferedImage out = toXuggleType(image, BufferedImage.TYPE_3BYTE_BGR);
/* Other time consuming processy stuff goes here */
/* Encode the frame to a video stream */
writer.encodeVideo(0,out,write_time-startTime, TimeUnit.NANOSECONDS);
}
private BufferedImage toType(BufferedImage source, int type) {
if( source.getType() != type ) {
BufferedImage temp = new BufferedImage(source.getWidth(),source.getHeight(),type);
temp.getGraphics().drawImage(source, 0, 0, null);
source = temp;
}
return source;
}
}
}
当图像处理很简单时,这工作得很好,但很快你就会遇到数十个并发线程试图做他们的事情,因为它变得有点复杂,因此为什么我问如何限制并发线程数而不丢弃任何线程。我不确定顺序在这种情况下特别重要,因为我认为不按顺序写入帧会将它们放在正确的位置,因为每个帧都指定了写入时间,但这需要测试。
最佳答案
But I need to guarantee that all threads that are created are run in sequence so no frames are dropped.
您在这里所说的意思是这个意思吗?如果是这样,那么您根本无法真正进行多线程处理,因为我知道在第 1 帧完成之前您无法开始处理第 2 帧。此时,您也可以按顺序处理帧并忽略线程。
或者,如果您的意思是其他内容,例如可以独立处理帧,但需要按顺序整理,那么这也是可行的。
无论如何 - 很少需要或有益于使用“原始”线程。正如其他人指出的那样,使用更高级别的并发实用程序(在本例中 ThreadPoolExecutor 是完美的)来监督这一点。
听起来 Runnable 也不是一个正确的选择,因为这意味着您将通过改变某些全局变量来返回处理的“结果”。相反,最好将此处理转换为可调用的并返回结果。这可能会消除线程安全问题,可能允许同时处理不同的帧而问题较少,并且允许您推迟每个结果的排序规则,直到您认为合适的点为止。
如果您想这样做,您可以执行以下操作:
// Create a thread pool with the given concurrency level
ExecutorService executor = Executors.newFixedThreadPool(Runtime.availableProcessors);
// Submit all tasks to the pool, storing the futures for further reference
// The ? here should be the class of object returned by your Callables
List<Future<?>> futures = new ArrayList<Future<?>>(NUM_FRAMES);
for (int i = 0; i < NUM_FRAMES; i++)
{
futures.add(executor.submit(createCallableForFrame(i)));
}
// Combine results using future.get()
// e.g. do something with frames 2 and 3:
mergeFrames(futures.get(2).get(), futures.get(3).get());
// In practice you'd probably iterate through the Futures but it's your call!
关于java - 如果之前的线程尚未完成,则对线程进行排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3441703/
从 Redis 获取消息时,onDone:(){print('done')} 从未起作用。 import 'package:dartis/dartis.dart' as redis show PubS
昨天我玩了一些vim脚本,并设法通过循环来对当前输入的内容进行状态栏预测(请参见屏幕截图(灰色+黄色栏))。 问题是,我不记得我是怎么得到的,也找不到我用于该vim魔术的代码片段(我记得它很简单):它
我尝试加载 bash_completion在我的 bash (3.2.25) 中,它不起作用。没有消息等。我在我的 .bashrc 中使用了以下内容 if [ -f ~/.bash_completio
我正在尝试构建一个 bash 完成例程,它将建议命令行标志和合适的标志值。例如在下面 fstcompose 命令我想比赛套路先建议 compose_filter= 标志,然后建议来自 [alt_seq
当我尝试在重定向符号后完成路径时,bash 完成的行为就好像它仍在尝试在重定向之前完成命令的参数一样。 例如: dpkg -l > /med标签 通过在 /med 之后点击 Tab我希望它完成通往 /
我的类中有几个 CAKeyframeAnimation 对象。 他们都以 self 为代表。 在我的animationDidStop函数中,我如何知道调用来自哪里? 是否有任何变量可以传递给 CAKe
我有一个带有 NSDateFormatter 的 NSTextField。格式化程序接受“mm/dd/yy”。 可以自动补全日期吗?因此,用户可以输入“mm”,格式化程序将完成当前月份和年份。 最佳答
有一个解决方案可以使用以下方法完成 NSTextField : - (NSArray *)control:(NSControl *)control textView:(NSTextView *)tex
我正在阅读 Passport 的文档,我注意到 serialize()和 deserialize() done()被调用而不被返回。 但是,当使用 passport.use() 设置新策略时在回调函数
在 ubuntu 11.10 上的 Firefox 8.0 中,尽管 img.complete 为 false,但仍会调用 onload 函数 draw。我设法用 setTimeout hack 解决
假设我有两个与两个并行执行的计算相对应的 future 。我如何等到第一个 future 准备好?理想情况下,我正在寻找类似于Python asyncio's wait且参数为return_when=
我正在寻找一种 Java 7 数据结构,其行为类似于 java.util.Queue,并且还具有“最终项目已被删除”的概念。 例如,应可以表达如下概念: while(!endingQueue.isFi
这是一个简单的问题。 if ($('.dataTablePageList')) { 我想做的是执行一个 if 语句,该语句表示如果具有 dataTablesPageList 类的对象也具有 menu
我用replaceWith批量替换了许多div中的html。替换后,我使用 jTruncate 来截断文本。然而它不起作用,因为在执行时,replaceWith 还没有完成。 我尝试了回调技巧 ( H
有没有办法调用 javascript 表单 submit() 函数或 JQuery $.submit() 函数并确保它完成提交过程?具体来说,在一个表单中,我试图在一个 IFrame 中提交一个表单。
我有以下方法: function animatePortfolio(fadeElement) { fadeElement.children('article').each(function(i
我刚刚开始使用 AndEngine, 我正在像这样移动 Sprite : if(pValueY < 0 && !jumping) { jumping =
我正在使用 asynctask 来执行冗长的操作,例如数据库读取。我想开始一个新 Activity 并在所有异步任务完成后呈现其内容。实现这一目标的最佳方法是什么? 我知道 onPostExecute
我有一个脚本需要命令名称和该命令的参数作为参数。 所以我想编写一个完成函数来完成命令的名称并完成该命令的参数。 所以我可以这样完成命令的名称 if [[ "$COMP_CWORD" == 1 ]];
我的应用程序有一个相当奇怪的行为。我在 BOOT_COMPLETE 之后启动我的应用程序,因此在我启动设备后它是可见的。 GUI 响应迅速,一切正常,直到我调用 finish(),按下按钮时,什么都没
我是一名优秀的程序员,十分优秀!