标签: threadpool

将ThreadLocal传播到从ExecutorService获取的新线程

我使用ExecutorService和Future(这里是示例代码)在一个带有超时的单独线程中运行一个进程(线程"生成"发生在AOP方面).

现在,主线程是Resteasy请求.Resteasy使用一个或多个ThreadLocal变量来存储我需要在Rest方法调用中的某个时刻检索的一些上下文信息.问题是,由于Resteasy线程在新线程中运行,因此ThreadLocal变量将丢失.

将Resteasy使用的任何ThreadLocal变量"传播"到新线程的最佳方法是什么?似乎Resteasy使用多个ThreadLocal变量来跟踪上下文信息,我想"盲目地"将所有信息传递给新线程.

我查看了子类化ThreadPoolExecutor并使用beforeExecute方法将当前线程传递给池,但我找不到将ThreadLocal变量传递给池的方法.

有什么建议吗?

谢谢

java multithreading thread-local resteasy threadpool

29
推荐指数
2
解决办法
3万
查看次数

C# - 何时在高活动性服务器中使用标准线程,ThreadPool和TPL

我最近一直在阅读很多关于线程的内容,因为我正在寻找能够处理多达10,000-20,000个客户端的高性能,可扩展的TCP服务器,每个客户端都通过基于命令的方式与服务器进行双向通信.系统.服务器将接收命令,并根据命令执行单个(或多个)任务.我的问题是如何在各种情况下适当地使用.NET线程构造,执行可能需要一分钟到几个小时的任务,具体取决于正在执行的工作.

最令我困惑的是,无论我在哪里阅读,我都会看到"使用手动创建的线程(或自定义线程池)来处理'长期运行'任务,并使用TPL执行短期任务或任务需要并行处理." 究竟什么长期任务?这是5秒,60秒,一小时吗?

我应该在什么时间框架中使用这三种创建线程的方法:

  • 手动创建的线程
  • .NET ThreadPool类
  • TPL

我想到的另一个问题如下 - 说我的服务器实际上连接了20,000个客户端,每个客户端每秒发送1个命令(可以转换为一个或多个任务).即使使用强大的硬件,我也不可能将过高的工作负载推送到我拥有的任何线程池/工作项队列中,从而最终在队列缓慢填充到最大值后生成OutOfMemoryException?

任何见解将不胜感激.

c# multithreading threadpool c#-4.0

28
推荐指数
3
解决办法
6059
查看次数

SynchronizationContext.Send和SynchronizationContext.Post有什么区别?

感谢Jeremy Miller在日常.NET开发的功能编程方面所做的出色工作,我有一个工作的命令执行器,它可以完成我想要的所有工作(对线程池进行繁重的工作,将结果或错误发送回同步环境,甚至发布进度回同步上下文),但我无法解释为什么它使用SynchronizationContext.Send从线程池和Synchronization.PostFunc传递到了做繁重的方法.我已经多次阅读过这些文档,但我对于它的不同之处并不是很有道理.我应该从一个叫做Send一个叫做一个被调用的事实中获得什么Post?我觉得魔术是Send"启动同步请求"和Post"启动异步请求" 这一事实,但这两个请求都来自线程池,需要发送/发回到UI线程.

有人可以解释这个区别,即使它只是一个助记符设备,让我知道何时选择一个而不是另一个?

在如此重要的情况下,这是我的测试代码,我用Post发进度回UI:

private Action _ExecuteCommand
                (SynchronizationContext context
                 , Action<int, int> progress
                 , Action<int, int> after)
{
    int count = 3;
    int accumulatedValue = 0;
    int threadId = Thread.CurrentThread.ManagedThreadId;
    for (int i = 0; i < count; i++)
    {
        Thread.Sleep(1000);
        context.Post(delegate { progress(i + 1, threadId); });
        accumulatedValue += i;
    }

    return () => …
Run Code Online (Sandbox Code Playgroud)

c# multithreading conceptual synchronizationcontext threadpool

27
推荐指数
1
解决办法
1万
查看次数

为什么OS线程被认为是昂贵的?

有许多解决方案适用于实现"用户空间"线程.无论是golang.org goroutines,python的绿色线程,C#的异步,erlang的进程等.这个想法是允许并发编程,即使是单个或有限数量的线程.

我不明白的是,为什么操作系统线程如此昂贵?正如我所看到的,无论哪种方式,你必须保存任务的堆栈(操作系统线程或用户空间线程),这是几十千字节,你需要一个调度程序在两个任务之间移动.

操作系统免费提供这两种功能.OS线程为什么要比"绿色"线程更昂贵?由于每个"任务"都有专用的OS线程,导致性能下降的原因是什么?

multithreading threadpool

27
推荐指数
4
解决办法
3330
查看次数

ASP.NET核心同步和异步控制器操作之间没有太大区别

我在控制器中编写了几个操作方法来测试ASP.NET内核中同步异步控制器操作之间的区别:

[Route("api/syncvasync")]
public class SyncVAsyncController : Controller
{
    [HttpGet("sync")]
    public IActionResult SyncGet()
    {
        Task.Delay(200).Wait();

        return Ok(new { });
    }

    [HttpGet("async")]
    public async Task<IActionResult> AsyncGet()
    {
        await Task.Delay(200);

        return Ok(new { });
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我加载测试同步终点: 在此输入图像描述

...后跟异步终点: 在此输入图像描述

如果我将延迟增加到1000毫秒,这是结果 在此输入图像描述 在此输入图像描述

正如您所看到的,每秒请求数没有太大差异- 我希望异步终点每秒处理更多请求.我错过了什么吗?

c# asp.net-mvc threadpool async-await asp.net-core

27
推荐指数
2
解决办法
1万
查看次数

ThreadPool.QueueUserWorkItem,带有lambda表达式和匿名方法

将两个参数传递给线程池上的新线程有时会很复杂,但看起来使用lambda表达式和匿名方法,我可以这样做:

public class TestClass
{
    public void DoWork(string s1, string s2)
    {
        Console.WriteLine(s1);
        Console.WriteLine(s2);
    }
}

try
{
    TestClass test = new TestClass();
    string s1 = "Hello";
    string s2 = "World";
    ThreadPool.QueueUserWorkItem(
        o => test.DoWork(s1, s2)
        );
}
catch (Exception ex)
{
    //exception logic
}
Run Code Online (Sandbox Code Playgroud)

现在,我肯定简化了这个例子,但这些要点是关键:

  • 传递的字符串对象是不可变的,因此是线程安全的
  • s1和s2变量在try块的范围内声明,我在将工作排队到线程池后立即退出,因此在此之后永远不会修改s1和s2变量.

这有什么问题吗?

另一种方法是创建一个实现具有3个成员的不可变类型的新类:test,s1和s2.这似乎是额外的工作,在这一点上没有任何好处.

c# lambda multithreading anonymous-methods threadpool

26
推荐指数
1
解决办法
2万
查看次数

删除ThreadPoolExecutor的所有排队任务

我有关于ThreadPoolExecutor的这个相当简单的问题.我有以下情况:我必须从队列中使用对象,为它们创建适当的工作人员任务并将它们提交给ThreadPoolExecutor.这很简单.但在关闭情况下,许多工作人员可能会排队等待执行.由于其中一个任务可能运行了一个小时,并且我希望相对快速地正常关闭应用程序,我想从ThreadPoolExecutor中丢弃所有排队的任务,而已经处理的任务应该正常完成.

ThreadPoolExecutor文档有一个remove()方法,但只允许删除特定的任务.purge()仅适用于已取消的Future任务.我的想法是清除队列中包含所有排队的任务.ThreadPoolExecutor提供对此内部队列的访问,但文档指出:

方法getQueue()允许访问工作队列以进行监视和调试.强烈建议不要将此方法用于任何其他目的.

所以抓住这个队列并清除它不是一个选择.此外,该文档的片段说:

当大量排队的任务被取消时,两个提供的方法remove(java.lang.Runnable)和purge()可用于协助存储回收.

怎么样?当然,我可以维护我提交给执行程序的所有任务的列表,在关闭的情况下,我遍历所有条目并使用remove()方法将它们从ThreadPoolExecutor中删除......但是...来吧,这是一个浪费记忆力和维护这份清单的麻烦.(例如,删除已执行的任务)

我感谢任何提示或解决方案!

java multithreading executorservice executor threadpool

26
推荐指数
4
解决办法
2万
查看次数

我在哪里创建和使用ScheduledThreadPoolExecutor,TimerTask或Handler?

我需要让我的RSS Feed阅读器每隔10分钟检查一次新帖子,然后在有新帖子的情况下解析它们.我还需要每分钟都更新UI.

我从不同的来源阅读和听到了不同的东西.我目前的理解是我可以ScheduledThreadPoolExecutor用来制作两个预定的线程,其中一个需要Handler更新UI.我不确定这些类或者最有效的使用方法TimerTask.

我也很不确定在哪里制作这些的子类.一位朋友建议TimerTaskFeedParser课堂上扩展为内部课程以使其更简单.但是,要以这种方式实现它,我必须使用该run()方法TimerTask而不重写它,这意味着我不能简单地使用我需要的参数来运行需要的函数.

简而言之,为此安排任务的最佳方法是什么,我将在哪里实现这些?

android handler threadpool timertask scheduledexecutorservice

25
推荐指数
1
解决办法
2万
查看次数

C# - ThreadPool QueueUserWorkItem使用?

就在我现在使用以下代码添加排队的线程.我不喜欢它.而且我的同事也不会因为他们不太了解C#.我想要的只是将一个方法排队在一个新线程中执行.

private static void doStuff(string parameter)
{
    // does stuff
}

// call (a)
ThreadPool.QueueUserWorkItem(a => doStuff("hello world"));
// call (b)
ThreadPool.QueueUserWorkItem(delegate { doStuff("hello world"); });
Run Code Online (Sandbox Code Playgroud)

那么还有其他用途ThreadPool.QueueUserWorkItem吗?

最好的是另一个1-Line-Call.如果可能,使用Func<>Action<>.


编辑:得到(b)答案和评论,我已经更喜欢它了.

c# multithreading delegates threadpool

25
推荐指数
2
解决办法
6万
查看次数

Python 3:Pool是否保持传递给map的原始数据顺序?

我编写了一个小脚本来分配4个线程之间的工作负载,并测试结果是否保持有序(关于输入的顺序):

from multiprocessing import Pool
import numpy as np
import time
import random


rows = 16
columns = 1000000

vals = np.arange(rows * columns, dtype=np.int32).reshape(rows, columns)

def worker(arr):
    time.sleep(random.random())        # let the process sleep a random
    for idx in np.ndindex(arr.shape):  # amount of time to ensure that
        arr[idx] += 1                  # the processes finish at different
                                       # time steps
    return arr

# create the threadpool
with Pool(4) as p:
    # schedule one map/worker for each row in the original data …
Run Code Online (Sandbox Code Playgroud)

python multithreading multiprocessing threadpool python-3.x

25
推荐指数
2
解决办法
9323
查看次数