JAVA线程池重用线程(JAVA Thread pool reusing threads)
大家。 我对使用Thread Pools有误解。 实际结果与此类的API描述不同。 当我在线程池中使用
LinkedBlockedQueue
并且它不重用线程时,线程池等待在构造函数中设置的KeepAliveTime,然后终止该线程并创建一个新线程。 当我将KeepAliveTime设置为较小时,例如1秒或更短时间它会删除线程并重新创建它,但如果我设置了一分钟,则不会创建新线程,因为MaxPoolSize
不允许它并且队列已经满了所以所有任务都被拒绝,但线程为keepAliveTime这次设置什么都不做。 我很新,不明白为什么它不重用这些线程。 在keepTimeAlive
到期后,它会杀死这些线程,如果队列已满,则会创建一个新线程。 为什么这样工作? 据我所知,如果线程在keepAliveTime期间处于空闲状态,它必须重用它。 它在我使用SynchronousQueue
时重用了线程,但没有使用LinkedBlockingQueue
。public class Main { private volatile int remainingTasksCount; private volatile static ThreadPoolExecutor consumer = new ThreadPoolExecutor(1, 2, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(3)); private static Runnable task = () -> { System.out.println(String.format("consumer %s, id %s, size %s, active count %s, queue %s", Thread.currentThread().getName(), Thread.currentThread().getId(), consumer.getPoolSize(), consumer.getActiveCount(), 3-consumer.getQueue().remainingCapacity())); String s = new String(); synchronized (s) { try { s.wait(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }; public static void main(String[] args) throws IOException { try { new Thread(() -> { while (true) { try { for (int i = 0; i < 5; i++) { consumer.submit(task); } System.out.println("PUSH TASKS"); synchronized (Thread.currentThread()) { Thread.currentThread().wait(10000); } } catch (Throwable th) { System.out.println(th); } } }).start(); } catch (Throwable th) { System.out.println(th); } }
OUTPUT
PUSH TASKS consumer pool-1-thread-1, id 15, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 1 consumer pool-1-thread-1, id 15, size 2, active count 1, queue 2 consumer pool-1-thread-1, id 15, size 2, active count 1, queue 0 Disconnected from the target VM, address: '127.0.0.1:64434', transport: 'socket' Process finished with exit code 1
但是下次生产者提交任务时,我得到了
RejectedExecutionException
如果我将
keepAliveTime
更改为1 Second
。 一切都运作良好,但创建新的线程。PUSH TASKS consumer pool-1-thread-2, id 16, size 2, active count 2, queue 3 consumer pool-1-thread-1, id 15, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 2 consumer pool-1-thread-1, id 15, size 2, active count 2, queue 1 consumer pool-1-thread-2, id 16, size 2, active count 1, queue 0 PUSH TASKS consumer pool-1-thread-3, id 17, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 2 consumer pool-1-thread-3, id 17, size 2, active count 2, queue 1 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 1 consumer pool-1-thread-3, id 17, size 2, active count 1, queue 0 consumer pool-1-thread-3, id 17, size 1, active count 1, queue 2 PUSH TASKS consumer pool-1-thread-4, id 18, size 2, active count 2, queue 3 consumer pool-1-thread-3, id 17, size 2, active count 2, queue 1 consumer pool-1-thread-4, id 18, size 2, active count 2, queue 1 consumer pool-1-thread-3, id 17, size 2, active count 1, queue 0 PUSH TASKS consumer pool-1-thread-3, id 17, size 2, active count 2, queue 2 consumer pool-1-thread-5, id 19, size 2, active count 2, queue 3 consumer pool-1-thread-3, id 17, size 2, active count 2, queue 1 consumer pool-1-thread-5, id 19, size 2, active count 2, queue 1 consumer pool-1-thread-3, id 17, size 2, active count 1, queue 0
如果有人能够解释我的错误,或者我错过了一些基本原则,我将很高兴
everyone. I have a misunderstanding of working with Thread Pools. The real result differs from API description of this class. When I am using
LinkedBlockedQueue
in Thread pool with it does not reuse threads, thread pool wait KeepAliveTime that was set in the constructor, then kill this thread and create a new one. When I set KeepAliveTime small, like 1 second or less it deletes thread a recreate it, but if I set for a minute new threads aren't created becauseMaxPoolSize
doesn't allow it and queue already full so all tasks rejected, but threads for which keepAliveTime set minute doing nothing this time. I am quite new and don't understand why it doesn't reuse these threads. afterkeepTimeAlive
expiration it kills these thread and if queue full, it creates a new one. Why it works this way? As far as I understood from API it has to reuse it if threads are idle during keepAliveTime. It reuses threads when I usedSynchronousQueue
, but notLinkedBlockingQueue
.public class Main { private volatile int remainingTasksCount; private volatile static ThreadPoolExecutor consumer = new ThreadPoolExecutor(1, 2, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(3)); private static Runnable task = () -> { System.out.println(String.format("consumer %s, id %s, size %s, active count %s, queue %s", Thread.currentThread().getName(), Thread.currentThread().getId(), consumer.getPoolSize(), consumer.getActiveCount(), 3-consumer.getQueue().remainingCapacity())); String s = new String(); synchronized (s) { try { s.wait(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }; public static void main(String[] args) throws IOException { try { new Thread(() -> { while (true) { try { for (int i = 0; i < 5; i++) { consumer.submit(task); } System.out.println("PUSH TASKS"); synchronized (Thread.currentThread()) { Thread.currentThread().wait(10000); } } catch (Throwable th) { System.out.println(th); } } }).start(); } catch (Throwable th) { System.out.println(th); } }
OUTPUT
PUSH TASKS consumer pool-1-thread-1, id 15, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 1 consumer pool-1-thread-1, id 15, size 2, active count 1, queue 2 consumer pool-1-thread-1, id 15, size 2, active count 1, queue 0 Disconnected from the target VM, address: '127.0.0.1:64434', transport: 'socket' Process finished with exit code 1
But next time producer submit tasks, I get
RejectedExecutionException
if I change
keepAliveTime
to1 Second
. Everything is working well, but creates new Threads.PUSH TASKS consumer pool-1-thread-2, id 16, size 2, active count 2, queue 3 consumer pool-1-thread-1, id 15, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 2 consumer pool-1-thread-1, id 15, size 2, active count 2, queue 1 consumer pool-1-thread-2, id 16, size 2, active count 1, queue 0 PUSH TASKS consumer pool-1-thread-3, id 17, size 2, active count 2, queue 3 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 2 consumer pool-1-thread-3, id 17, size 2, active count 2, queue 1 consumer pool-1-thread-2, id 16, size 2, active count 2, queue 1 consumer pool-1-thread-3, id 17, size 2, active count 1, queue 0 consumer pool-1-thread-3, id 17, size 1, active count 1, queue 2 PUSH TASKS consumer pool-1-thread-4, id 18, size 2, active count 2, queue 3 consumer pool-1-thread-3, id 17, size 2, active count 2, queue 1 consumer pool-1-thread-4, id 18, size 2, active count 2, queue 1 consumer pool-1-thread-3, id 17, size 2, active count 1, queue 0 PUSH TASKS consumer pool-1-thread-3, id 17, size 2, active count 2, queue 2 consumer pool-1-thread-5, id 19, size 2, active count 2, queue 3 consumer pool-1-thread-3, id 17, size 2, active count 2, queue 1 consumer pool-1-thread-5, id 19, size 2, active count 2, queue 1 consumer pool-1-thread-3, id 17, size 2, active count 1, queue 0
I will be glad if someone could explain me my fault, or something basic principle that I missed
原文:https://stackoverflow.com/questions/47157431
最满意答案
好的,重新阅读你的问题后,听起来你只需要访问一个名称与属性相似的变量。 假设它是一个全局变量,请这样做:
$(document).ready(function(){ $('textarea[tinymce]').each(function(){ var tinymceopts = $(this).attr('tinymce'); $(this).tinymce(window[tinymceopts]); });
您现在引用一个变量window.basicoptions,而不是将字符串'basicoptions'传递给
tinymce
方法,它应该映射到您的var basicoptions
变量,假设范围确实在全局级别。 如果不是,只需将window
替换为适用的命名空间即可。Ok after re-reading your question, it sounds like you just need to access a variable with the name similar to the attribute. Assuming it's a global variable, do it like this:
$(document).ready(function(){ $('textarea[tinymce]').each(function(){ var tinymceopts = $(this).attr('tinymce'); $(this).tinymce(window[tinymceopts]); });
Instead of passing the string 'basicoptions' to the
tinymce
method, you're now referencing a variablewindow.basicoptions
which should map to yourvar basicoptions
variable, assuming the scope was indeed at the global level. If it wasn't, just replacewindow
with the applicable namespace.
相关问答
更多-
使用:not()选择器。 $('.funding-plan-container:not([data-timestamp])') 顺便说一句,这是一个有效的选择器API选择器,所以它不是特定于jQuery的。 它将与querySelectorAll()和CSS (给定浏览器支持)一起使用 。 Use the :not() selector. $('.funding-plan-container:not([data-timestamp])') This, by the way, is a valid Sel ...
-
好的,重新阅读你的问题后,听起来你只需要访问一个名称与属性相似的变量。 假设它是一个全局变量,请这样做: $(document).ready(function(){ $('textarea[tinymce]').each(function(){ var tinymceopts = $(this).attr('tinymce'); $(this).tinymce(window[tinymceopts]); }); 您现在引用一个变量window.basicoptions,而不是将字符串 ...
-
您可以减少它并同时解决您的选择器问题,只需使用.val()如下所示: var hashmap = { htmlcss: "HTML/CSS Coding", php: "PHP Coding", jscript: "Javascript and jQuery Coding", improv: "General Website Improvements", towp: "Website Conversion to Wordpress", wptheme: "Wordpress Th ...
-
jQuery“按属性”选择器(jQuery “by attribute” selector)[2022-12-25]
我认为这是因为.val在input上设置属性 。 然后使用[value="aaa"]查看input的属性,但实际上并没有改变。 如果您更改了如何使用jQuery将输入的值设置为: $("input:first").attr("value", "aaa"); 然后检查长度,你会得到你期待的结果。 小提琴: http : //jsfiddle.net/gromer/ZnbpE/ 属性和属性之间的区别: http : //blog.jquery.com/2011/05/12/jquery-1-6-1-releas ... -
$('div[id="'+find+"div"'"]')无效Javascript语法: $( // jQuery function 'div[id="' // String + find // Add variable + "div" // Add String '"]' // Unexpected string! - Error 有效语法的一个例子是: $('div[id="'+find+'div"]') 但是,由于它是一个id,您可以使用id选择器 ...
-
选择器"[toggle-state='" + newState + "']"将匹配文档中具有属性toggle-state设置为newState每个元素(在本例中为“OFF”)。 将该选择器用作jQuery的参数将创建一个包含结果匹配集的jQuery对象。 这种结构正在被归还。 这是一个简单的演示 function switchOff(){ var newState = "OFF"; return $("[toggle-state='" + newState + "']") } $("#re ...
-
Jquery属性选择器单击(Jquery Attribute selector click)[2021-08-19]
当前代码的问题是当元素具有属性时附加事件。 之后更改属性的事实不会删除该事件处理程序,因此始终会调用它。 有几种方法可以解决这个问题。 第一种是使用委托事件处理程序,它始终考虑当前属性值: $(document).on('click', 'a[data-spinner="true"]', function() { $(this).attr("data-spinner", false); alert("clicked"); }); 另一种方法是检查点击处理程序本身内的属性状态: $("a[d ... -
首先,如果人们花时间为您提供答案,您至少可以努力接受这些答案 。 其次,关于您的问题,您可以使用filter()或检查值是否为空: $('input[value!=""]:checkbox').addClass('selected'); http://jsfiddle.net/niklasvh/pEK3c/ 要么 $('input:checkbox').filter(function(){ return this.value.length; }).addClass('selected'); 示例 ...
-
Actualy [display=block]不是正确的选择器 使用:可见选择器 alert($("div#keylist ul li:visible").first().position().top); 我想这就是你需要的 alert($('ul > li').filter(function(){ return $(this).css('display') == 'block'; }).first().text()); 演示 Actualy [display=block] is not a rig ...
-
jQuery选择器属性范围(jQuery selector attribute range)[2022-05-31]
您可以使用.filter()执行更复杂的查询: $('#mytable td').filter(function() { return ($(this).parent().attr('attr-y') > 3 && $(this).parent().attr('attr-y') < 5) && ($(this).attr('attr-x') == 4) }) .css('background-color', 'aqua'); 示例: http : //jsfiddle.net/8w ...