javascript

java

python

c#

android

c++

node.js

php

html

jquery

ios

reactjs

css

.net

git

ruby-on-rails

sql

c

ruby

string

为什么我看不到大多数高级语言的管道运算符?

在Unix Shell编程中,管道运算符是一个非常强大的工具。 使用少量的核心实用程序,系统语言(如C)和脚本语言(如Python),您可以构建极其紧凑且功能强大的Shell脚本,这些脚本将由操作系统自动并行化。

显然,这是一个非常强大的编程范例,但是我没有将管道视为除Shell脚本之外的任何语言的第一类抽象。 使用管道复制脚本功能所需的代码似乎总是很复杂。

所以我的问题是,为什么在现代高级语言(如C#,Java等)中看不到类似于Unix管道的东西? 是否有支持一流管道的语言(shell脚本除外)? 这是一种表达并发算法的方便,安全的方法吗?

以防万一有人提出它,我看了看F#管道转发运算符(forward pipe operator),它看起来更像是函数应用程序运算符。 据我所知,它对数据应用了一个函数,而不是将两个流连接在一起,但是我可以接受更正。

后记:在研究实现协程的同时,我意识到存在某些相似之处。 马丁·沃尔夫(Martin Wolf)在一篇博客文章中描述了一个与我类似的问题,只是用协程而不是管道。

trans by 2020-08-12T06:57:47Z

为什么在.Net(4.0)中ConcurrentBag <T>这么慢? 我做错了吗?

在开始一个项目之前,我编写了一个简单的测试来比较(System.Collections.Concurrent)中的ConcurrentBag与锁定&列表的性能。 我非常惊讶ConcurrentBag比用一个简单的List锁定慢十倍以上。 据我了解,当读者和作家是同一线程时,ConcurrentBag效果最佳。 但是,我没有想到它的性能不会比传统锁差很多。

我已经使用两个Parallel for循环对列表/包进行读写操作进行了测试。 但是,写入本身显示出巨大的差异:

private static void ConcurrentBagTest()
   {
        int collSize = 10000000;
        Stopwatch stopWatch = new Stopwatch();
        ConcurrentBag<int> bag1 = new ConcurrentBag<int>();

        stopWatch.Start();


        Parallel.For(0, collSize, delegate(int i)
        {
            bag1.Add(i);
        });


        stopWatch.Stop();
        Console.WriteLine("Elapsed Time = {0}", 
                          stopWatch.Elapsed.TotalSeconds);
 }

在我的机器上,这需要3-4秒的时间才能运行,而此代码为0.5-0.9秒:

       private static void LockCollTest()
       {
        int collSize = 10000000;
        object list1_lock=new object();
        List<int> lst1 = new List<int>(collSize);

        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();


        Parallel.For(0, collSize, delegate(int i)
            {
                lock(list1_lock)
                {
                    lst1.Add(i);
                }
            });

        stopWatch.Stop();
        Console.WriteLine("Elapsed = {0}", 
                          stopWatch.Elapsed.TotalSeconds);
       }

正如我提到的,进行并发读取和写入对并发袋测试没有帮助。 我是在做错什么,还是这个数据结构真的很慢?

[编辑]-我删除了任务,因为在这里我不需要它们(完整的代码有另一个任务阅读)

[编辑]非常感谢您的回答。 我很难选择“正确的答案”,因为这似乎是几个答案的组合。

正如Michael Goldshteyn所指出的,速度实际上取决于数据。Darin指出,应该有更多的争用来使ConcurrentBag更快,而Parallel.For不必启动相同数量的线程。 要带走的一点是不要对锁进行任何不必要的操作。 在上述情况下,我看不到自己在锁内执行任何操作,除非可能是将值分配给temp变量。

此外,sixlettervariables指出,尽管我尝试以相反的顺序运行原始测试,并且ConcurrentBag仍然较慢,但是碰巧正在运行的线程数也可能会影响结果。

我从启动15个任务开始进行了一些测试,结果取决于其他因素。 但是,对于最多一百万次插入,ConcurrentBag的性能几乎与锁定列表一样好或更好。 超过一百万,锁定有时似乎要快得多,但是我的项目可能永远不会拥有更大的数据结构。这是我运行的代码:

        int collSize = 1000000;
        object list1_lock=new object();
        List<int> lst1 = new List<int>();
        ConcurrentBag<int> concBag = new ConcurrentBag<int>();
        int numTasks = 15;

        int i = 0;

        Stopwatch sWatch = new Stopwatch();
        sWatch.Start();
         //First, try locks
        Task.WaitAll(Enumerable.Range(1, numTasks)
           .Select(x => Task.Factory.StartNew(() =>
            {
                for (i = 0; i < collSize / numTasks; i++)
                {
                    lock (list1_lock)
                    {
                        lst1.Add(x);
                    }
                }
            })).ToArray());

        sWatch.Stop();
        Console.WriteLine("lock test. Elapsed = {0}", 
            sWatch.Elapsed.TotalSeconds);

        // now try concurrentBag
        sWatch.Restart();
        Task.WaitAll(Enumerable.Range(1, numTasks).
                Select(x => Task.Factory.StartNew(() =>
            {
                for (i = 0; i < collSize / numTasks; i++)
                {
                    concBag.Add(x);
                }
            })).ToArray());

        sWatch.Stop();
        Console.WriteLine("Conc Bag test. Elapsed = {0}",
               sWatch.Elapsed.TotalSeconds);
trans by 2020-08-11T06:56:06Z

并发-新的ASP.NET MVC 6标识中AspNetUsers表中的ConcurrencyStamp列的用途是什么?

新的ASP.NET MVC 6标识中的AspNetUsers表中的AspNetRoles列的用途是什么?

这是AspNetRoles表的数据库架构:

enter image description here

它也位于AspNetRoles表中:

enter image description here

我记得ASP.NET MVC 5标识中没有它。

到目前为止,我已经注意到,它似乎具有GUID值,因为它是用以下代码定义的:

/// <summary>
/// A random value that must change whenever a user is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();

但是,该文档不足以让我了解在哪种情况下使用它。

trans by 2020-08-10T23:00:23Z

Java-石英:防止Jobs.xm中的作业并发实例

这应该真的很容易。 我使用的是在Apache Tomcat 6.0.18下运行的Quartz,我有一个jobs.xml文件,该文件设置了每分钟运行的计划作业。

我想做的是,如果下一个触发时间到来时该作业仍在运行,则我不想开始新的作业,因此可以让旧实例完成。

有没有办法在Jobs.xml中指定此设置(防止并发实例)?

如果不是,是否有一种方法可以共享对应用程序的Job实现中的内存中单例的访问(是否通过JobExecutionContext?),以便我自己处理并发性? (并检测先前的实例是否正在运行)


更新:在文档中苦苦挣扎之后,我正在考虑以下两种方法,但是要么不知道如何使它们工作,要么有问题。

  1. 使用StatefulJob。 这样可以防止并发访问...但是我不确定如果使用它,还会产生其他副作用,我也想避免以下情况:

    假设触发时间是每分钟,即触发#0 =在时间0,触发#1 = 60000毫秒,#2 = 120000,#3 = 180000,依此类推,而在时间0的触发#0触发了我的工作,耗时130000毫秒。 对于普通作业,它将在作业触发器#0仍在运行时执行触发器#1和#2。 使用StatefulJob,它将在#0在130000之后完成后立即执行触发器#1和#2。我不希望那样,我不希望#1和#2运行,而下一个运行作业的触发器应该 发生在#3(180000msec)。 因此,我仍然必须对StatefulJob进行其他操作才能使其按我想要的方式工作,因此使用它并没有太大优势。

  2. 使用TriggerListener从vetoJobExecution()返回true。

    尽管实现接口似乎很简单,但是我必须弄清楚如何以声明方式设置一个TriggerListener实例。 找不到xml文件的文档。

  3. 使用实现Job的类拥有的<trigger><simple>...</simple></trigger>共享线程安全对象(例如,信号量或其他)。

    我不喜欢通过Tomcat / Quartz下的<trigger><simple>...</simple></trigger>关键字使用单例的想法,不确定是否有副作用。 另外,我真的不希望它们是真正的单例,而只是与特定工作定义相关联的东西。

  4. 实现我自己的触发器,该触发器扩展了SimpleTrigger并包含可以运行自己的TriggerListener的共享状态。

    同样,我不知道如何设置XML文件以使用此触发器,而不是标准<trigger><simple>...</simple></trigger>

trans by 2020-08-09T10:50:40Z

java-如果完全像compareAndSet那样实现weakCompareAndSet会失败吗?

(请注意,此问题不是关于CAS的,而是关于“可能偶然失败”的Javadoc)。

这两个方法与AtomicInteger类的两种方法之间的Javadoc唯一区别是,weakCompareAndSet包含以下注释:“可能会虚假失败”。

现在,除非我的眼睛因某种咒语而被欺骗,否则这两种方法的确看起来完全一样:

public final boolean compareAndSet(int expect, int update) {
  return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

/* ...
 * May fail spuriously.
 */
public final boolean weakCompareAndSet(int expect, int update) {
  return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

因此,我意识到“ May”并不意味着“ Must”,但是为什么我们不都开始将其添加到我们的代码库中:

public void doIt() {
    a();
}

/**
 * May fail spuriously
 */
public void weakDoIt() {
    a();
}

我对那个看上去与compareAndSet()一样的弱CompareAndSet()感到困惑,但是“可能会虚假地失败”,而另一个却不能。

显然,“弱”和“虚假失败”与“先发生”排序有关,但是我对这两种AtomicInteger(和AtomicLong等)方法仍然感到困惑:因为显然它们调用的是完全相同的不安全方法 .compareAndSwapInt方法。

我对Java 1.5引入AtomicInteger感到特别困惑,因此在Java内存模型更改后(显然,它不能“在1.4中错误地失败”,但是其行为更改为“在1.5中不可错误地失败”) 。

trans by 2020-08-09T00:07:00Z

可直接访问的数据结构J

我有以下情况:

  1. 只能扩展的数据结构(仅适用于在尾部添加内容)
  2. 我需要能够跟踪我已经拥有的元素看过(我有一个索引,理想情况下,我希望能够开始再次遍历此特定元素的列表)
  3. 我希望读取内容永远不会受到阻碍,并增加仅锁定队列尾部而不是锁定队列的新元素整个队列

这是一个由多个线程大量修改的结构。

最好的数据结构是什么?

数组列表。 能够直接访问使用索引看到的最后一个元素是理想的选择,但是它会导致并发修改异常。 我可以使其同步,但要避免锁定(或除最后一个元素之外的任何锁定,因为它是唯一可能存在并发写入以添加新元素的锁定)

ConcurrentLinkedQueue。 这样可以解决我的并发问题,但是有一个问题,就是我必须存储迭代的当前位置而不是整数索引。 这样做的问题是,它返回一个弱一致性的迭代器,该迭代器不能保证返回自创建迭代器以来已添加到列表中的新对象(来源:javadoc)

以索引为键的ConcurrentHashMap。 这样的好处是我可以直接访问与正确索引相对应的数据,但是存在的问题是没有“ getNext”运算符可以使我高效地从索引遍历元素到索引+ 1等。

向量这将解决我的大多数问题,即允许某些不会引发并发修改异常并允许直接访问的东西。 但是,由于所有方法都是同步的,因此与数组列表相比,性能较差。 鉴于我只想扩展结构,而不是在中间插入记录,因此我不愿意采用这种笨重的解决方案,因为在这种情况下,读取也会遭受性能损失(而鉴于我的用例,元素的索引 从不实际更改,因此无需同步不是尾部的读取)

自定义数据结构:保留要存储的对象的数组以及指向该数组尾部的指针(最后一个元素集),在插入新对象时,锁定尾部和尾部指向的对象。 当对象超过其当前大小时,将执行锁定调整大小操作。

什么是最佳策略/其他更有效的实施方式?

trans by 2020-08-07T00:43:54Z

多线程-如何在Clojure中启动线程?

我已经读了很多关于Clojure在并发性方面的知识,但是我读过的所有教程都没有真正解释如何创建线程。 您只是做(.start(Thread。func)),还是我错过了另一种方法?

trans by 2020-08-05T07:41:07Z

java-关闭后如何重用线程池

我有一个.csv文件,其中包含超过7000万行,其中每行将生成一个Runnable,然后由线程池执行。 此Runnable将一条记录插入Mysql。

而且,我想记录csv文件的位置,以便RandomAccessFile找到。 该位置被写入文件。当线程池中的所有线程完成时,我想写入此记录。因此调用ThreadPoolExecutor.shutdown()。 但是,当更多行出现时,我又需要一个线程池。 我该如何重用当前的线程池而不是创建一个新的线程池。

代码如下:

public static boolean processPage() throws Exception {

    long pos = getPosition();
    long start = System.currentTimeMillis();
    raf.seek(pos);
    if(pos==0)
        raf.readLine();
    for (int i = 0; i < PAGESIZE; i++) {
        String lineStr = raf.readLine();
        if (lineStr == null)
            return false;
        String[] line = lineStr.split(",");
        final ExperienceLogDO log = CsvExperienceLog.generateLog(line);
        //System.out.println("userId: "+log.getUserId()%512);

        pool.execute(new Runnable(){
            public void run(){
                try {
                    experienceService.insertExperienceLog(log);
                } catch (BaseException e) {
                    e.printStackTrace();
                }
            }
        });

        long end = System.currentTimeMillis();
    }

    BufferedWriter resultWriter = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(new File(
                    RESULT_FILENAME), true)));
    resultWriter.write("\n");
    resultWriter.write(String.valueOf(raf.getFilePointer()));
    resultWriter.close();
    long time = System.currentTimeMillis()-start;
    System.out.println(time);
    return true;
}

谢谢 !

trans by 2020-08-03T21:06:08Z

go-为什么添加并发会使该golang代码变慢?

我已经修改了一些Go代码,以解决与我姐夫玩的视频游戏有关的我的好奇心。

本质上,下面的代码模拟了游戏中与怪物的互动,以及他期望他们在失败后掉落物品的频率。 我遇到的问题是,我希望像这样的一段代码对于并行化是完美的,但是当我并发添加时,完成所有模拟所花费的时间往往会使原始代码的速度降低4-6倍 没有并发。

为了让您更好地理解代码的工作方式,我提供了三个主要功能:交互功能,它是玩家和怪物之间的简单交互。 如果怪物掉落物品,则返回1,否则返回0。 模拟功能会运行多个互动,并返回互动结果的一部分(即1和0代表成功/失败的互动)。 最后,有一个测试函数,它运行一组模拟并返回一部分模拟结果,这些结果是导致掉落物品的交互总数。 这是我试图并行运行的最后一个函数。

现在,我可以理解,如果我为要运行的每个测试创建一个goroutine,为什么代码会变慢。 假设我正在运行100个测试,则在MacBook Air的4个CPU上的每个goroutine之间进行上下文切换会降低性能,但是我只创建与我拥有的处理器一样多的goroutine,并将测试次数除以 goroutines。 我希望这实际上可以提高代码的性能,因为我可以并行运行每个测试,但是,当然,我会遇到严重的问题。

我很想知道为什么会这样,所以任何帮助将不胜感激。

以下是不带go例程的常规代码:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    NUMBER_OF_SIMULATIONS = 1000
    NUMBER_OF_INTERACTIONS = 1000000
    DROP_RATE = 0.0003
)

/**
 * Simulates a single interaction with a monster
 *
 * Returns 1 if the monster dropped an item and 0 otherwise
 */
func interaction() int {
    if rand.Float64() <= DROP_RATE {
        return 1
    }
    return 0
}

/**
 * Runs several interactions and retuns a slice representing the results
 */
func simulation(n int) []int {
    interactions := make([]int, n)
    for i := range interactions {
        interactions[i] = interaction()
    }
    return interactions
}

/**
 * Runs several simulations and returns the results
 */
func test(n int) []int {
    simulations := make([]int, n)
    for i := range simulations {
        successes := 0
        for _, v := range simulation(NUMBER_OF_INTERACTIONS) {
            successes += v
        }
        simulations[i] = successes
    }
    return simulations
}

func main() {
    rand.Seed(time.Now().UnixNano())
    fmt.Println("Successful interactions: ", test(NUMBER_OF_SIMULATIONS))
}

并且,这是带有goroutines的并发代码:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "runtime"
)

const (
    NUMBER_OF_SIMULATIONS = 1000
    NUMBER_OF_INTERACTIONS = 1000000
    DROP_RATE = 0.0003
)

/**
 * Simulates a single interaction with a monster
 *
 * Returns 1 if the monster dropped an item and 0 otherwise
 */
func interaction() int {
    if rand.Float64() <= DROP_RATE {
        return 1
    }
    return 0
}

/**
 * Runs several interactions and retuns a slice representing the results
 */
func simulation(n int) []int {
    interactions := make([]int, n)
    for i := range interactions {
        interactions[i] = interaction()
    }
    return interactions
}

/**
 * Runs several simulations and returns the results
 */
func test(n int, c chan []int) {
    simulations := make([]int, n)
    for i := range simulations {
        for _, v := range simulation(NUMBER_OF_INTERACTIONS) {
            simulations[i] += v
        }
    }
    c <- simulations
}

func main() {
    rand.Seed(time.Now().UnixNano())

    nCPU := runtime.NumCPU()
    runtime.GOMAXPROCS(nCPU)
    fmt.Println("Number of CPUs: ", nCPU)

    tests := make([]chan []int, nCPU)
    for i := range tests {
        c := make(chan []int)
        go test(NUMBER_OF_SIMULATIONS/nCPU, c)
        tests[i] = c
    }

    // Concatentate the test results
    results := make([]int, NUMBER_OF_SIMULATIONS)
    for i, c := range tests {
        start := (NUMBER_OF_SIMULATIONS/nCPU) * i
        stop := (NUMBER_OF_SIMULATIONS/nCPU) * (i+1)
        copy(results[start:stop], <-c)
    }

    fmt.Println("Successful interactions: ", results)
}

更新(13/12/13 18:05)

我在下面添加了新版本的并发代码,该代码根据下面“系统”的建议为每个goroutine创建一个新的Rand实例。 现在,与串行版本的代码相比,我看到了非常小的速度提升(总花费时间减少了15-20%)。 我很想知道为什么我没有将时间减少75%左右的时间,因为我将工作量分散在MBA的4个核心上。 有没有人有其他建议可以帮助您?

package main

import (
    "fmt"
    "math/rand"
    "time"
    "runtime"
)

const (
    NUMBER_OF_SIMULATIONS = 1000
    NUMBER_OF_INTERACTIONS = 1000000
    DROP_RATE = 0.0003
)

/**
 * Simulates a single interaction with a monster
 *
 * Returns 1 if the monster dropped an item and 0 otherwise
 */
func interaction(generator *rand.Rand) int {
    if generator.Float64() <= DROP_RATE {
        return 1
    }
    return 0
}

/**
 * Runs several interactions and retuns a slice representing the results
 */
func simulation(n int, generator *rand.Rand) []int {
    interactions := make([]int, n)
    for i := range interactions {
        interactions[i] = interaction(generator)
    }
    return interactions
}

/**
 * Runs several simulations and returns the results
 */
func test(n int, c chan []int) {
    source := rand.NewSource(time.Now().UnixNano())
    generator := rand.New(source)
    simulations := make([]int, n)
    for i := range simulations {
        for _, v := range simulation(NUMBER_OF_INTERACTIONS, generator) {
            simulations[i] += v
        }
    }
    c <- simulations
}

func main() {
    rand.Seed(time.Now().UnixNano())

    nCPU := runtime.NumCPU()
    runtime.GOMAXPROCS(nCPU)
    fmt.Println("Number of CPUs: ", nCPU)

    tests := make([]chan []int, nCPU)
    for i := range tests {
        c := make(chan []int)
        go test(NUMBER_OF_SIMULATIONS/nCPU, c)
        tests[i] = c
    }

    // Concatentate the test results
    results := make([]int, NUMBER_OF_SIMULATIONS)
    for i, c := range tests {
        start := (NUMBER_OF_SIMULATIONS/nCPU) * i
        stop := (NUMBER_OF_SIMULATIONS/nCPU) * (i+1)
        copy(results[start:stop], <-c)
    }

    fmt.Println("Successful interactions: ", results)
}

更新(01/13/13 17:58)

谢谢大家对解决我的问题的帮助。 我终于得到了我一直在寻找的答案,所以我想在这里对那些有相同问题的人做一下总结。

从本质上讲,我有两个主要问题:首先,即使我的代码令人尴尬地并行执行,但是当我在可用处理器之间分配代码时,它的运行速度却变慢了;其次,该解决方案带来了另一个问题,即我的串行代码运行了两次。与在单个处理器上运行的并发代码一样慢,您可能希望大致相同。在这两种情况下,问题都是随机数生成器函数Rand。基本上,这是rand.Float64软件包提供的便利函数。在该程序包中,每个便捷功能都创建并使用了Rand结构的全局实例。此全局Rand实例具有与其关联的互斥锁。由于使用了此便利函数,因此我无法真正并行化代码,因为每个goroutine必须排队才能访问全局Rand实例。解决方案(如下面的“系统”所示)是为每个goroutine创建一个Rand结构的单独实例。这解决了第一个问题,但创建了第二个问题。

第二个问题是我的非并行并发代码(即,仅使用一个处理器运行的并发代码)的运行速度是顺序代码的两倍。 这样做的原因是,即使我仅使用单个处理器和单个goroutine运行,该goroutine仍具有自己创建的Rand结构的实例,并且在创建时没有互斥锁。 顺序代码仍在使用rand.Float64便利函数,该便利函数使用了受全局互斥锁保护的Rand实例。 获得该锁的成本导致顺序代码的运行速度慢了一倍。

因此,故事的寓意是,每当性能很重要时,请确保您创建Rand结构的实例并从中调用所需的函数,而不是使用程序包提供的便捷函数。

trans by 2020-08-02T05:32:34Z

多线程-如何在Java 5中使用ExecutorService实现任务优先级?

我正在实现一种线程池机制,在该机制中我想执行具有不同优先级的任务。 我希望有一个很好的机制,通过该机制,我可以向服务提交高优先级的任务,并将其安排在其他任务之前。 任务的优先级是任务本身的内在属性(无论我将其表示为PriorityBlockingQueue还是ThreadPoolExecutor对我来说都不重要)。

现在,从表面上看,我可以使用PriorityBlockingQueue作为我的ThreadPoolExecutor中的任务队列,但是该队列包含Runnable对象,这些对象可能是我提交给它的Runnable任务,也可能不是。 此外,如果我提交了Callable任务,则尚不清楚如何映射。

有没有办法做到这一点? 我真的不希望自己为此付出代价,因为我更有可能以这种方式弄错它。

(顺便说一句,是的,我知道在这样的情况下,低优先级工作可能会挨饿。对于可以合理保证公平的解决方案,加分(?!))

trans by 2020-08-01T17:59:55Z

java-ConcurrentHashMap如何在内部工作?

我正在阅读有关Java并发性的Oracle官方文档,并且想知道由Java返回的ConcurrentHashMap之间的区别是什么?

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

并使用例如

ConcurrentHashMap。我假设我在HashMap上使用synchronizedCollection(Collection<T> c)。我知道一般而言,同步集合实际上只是HashMap的装饰器,因此很明显ConcurrentHashMap的内部结构有所不同。 您是否掌握有关这些实施细节的信息?

编辑:我意识到源代码是公开可用的:ConcurrentHashMap.java

trans by 2020-07-31T04:46:51Z

haskell-TVar和TMV之间的区别

我已经看到[Handle]是一个简单的容器,而forkIOMVar相同,这意味着它具有锁等,但在STM monad中。 我想知道为什么这是必要的,因为STM的想法是不必使用锁。

那么,如果您有一个想像的类型,例如[Handle],并且想要在forkIO的线程之间使用的套接字句柄列表,该使用哪一个?

trans by 2020-07-31T03:44:00Z

java-如何从执行程序中正确捕获RuntimeException?

说我有以下代码:

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(myRunnable);

现在,如果myRunnable抛出RuntimeExcpetion,该如何捕捉? 一种方法是将自己的ThreadFactory实现提供给newSingleThreadExecutor(),并为其中的Threads设置自定义uncaughtExceptionHandlers。 另一种方法是将myRunnable包装到包含try-catch -block的本地(匿名)Runnable。 也许还有其他类似的解决方法。 但是...以某种方式感觉很脏,我觉得这不应该那么复杂。 有没有干净的解决方案?

trans by 2020-07-29T08:34:55Z

如何运行并发单元测试?

如何使用junit进行并发测试?

假设我有一堂课

public class MessageBoard
{
    public synchronized void postMessage(String message)
    {
        ....
    }

    public void updateMessage(Long id, String message)
    {
        ....
    }
}

我想同时测试对该postMessage的多重访问。有什么建议吗? 我希望针对我所有的setter函数(或任何涉及create / update / delete操作的方法)运行这种并发测试。

trans by 2020-07-27T04:48:42Z

java-线程相似性是什么意思?

我在某处听说过“线程亲和力”和“线程亲和力执行器”。 但是我至少在java中找不到合适的参考。 有人可以告诉我这是怎么回事吗?

trans by 2020-07-25T14:46:50Z

垃圾回收-如何减少Java并发模式失败和过多的G

在Java中,并发模式故障意味着并发收集器无法从持久性和永久性gen释放足够的内存空间,而不得不放弃并让完整的stop-the-world gc介入。最终结果可能会非常昂贵。

我了解这个概念,但从未对它有全面的了解
A)可能导致并发模式故障的原因和
B)有什么解决方案?

这种不清楚的状态使我在编写/调试代码时没有太多提示,并且经常不得不在没有特殊原因的情况下四处寻找从Foo到Bar的性能标志,只需尝试一下即可。

我想在这里向开发人员学习,您的经验如何? 如果您遇到了这样的性能问题,是什么原因以及如何解决?

如果您有编码建议,请不要太笼统。 谢谢!

trans by 2020-07-22T23:19:28Z

jsf-在Java EE中手动启动新线程是否安全?

对于在会话范围内的JSF托管Bean中生成线程是否安全,我找不到确切的答案。 线程需要在无状态EJB实例(依赖项注入到托管bean)上调用方法。

背景是我们需要花费很长时间来生成报告。 由于服务器设置我们无法更改,这导致HTTP请求超时。 因此,其想法是启动一个新线程,并使其生成报告并临时存储它。 同时,JSF页面显示一个进度条,轮询托管bean直到生成完成,然后再次请求下载存储的报告。 这似乎可行,但我想确定自己正在做的事情不是黑客。

trans by 2020-07-22T05:48:38Z

消息传递和共享内存并发模型之间有什么区别?

如果我错了,请纠正我,但令我惊讶的是,这里从未有人问过这个问题...

trans by 2020-07-17T17:43:52Z

完全取代ASP.Net的会话

ASP.Net会话对于传统的WebForms应用程序来说似乎很完美,但是它们所做的某些事情对于现代AJAX和MVC应用程序来说是一个严重的问题。

具体来说,只有三种方法可以访问ASP.Net提供程序:

  1. 锁定读写(默认)-该会话从HttpContext.Current.Session触发直到ReleaseRequestState触发都被锁定。 如果浏览器一次发出3个请求,它们将在服务器上排队。 这是MVC 2中的唯一选项,但是MVC 3允许...

  2. 非锁定只读-会话未锁定,但无法保存到。 但是,这似乎是不可靠的,因为某些读取似乎再次锁定了会话。

  3. 会话已禁用-任何读取或写入会话的尝试都将引发异常。

但是,使用现代MVC应用程序,我会同时发生很多AJAX事件-我不希望它们在服务器上排队,但我希望它们能够写入会话。

我想要的是第四个模式:脏读,最后写胜

我认为(很高兴得到纠正)做到这一点的唯一方法是完全替换ASP.Net的会话。 我可以编写自己的提供程序,但是ASP仍会使用其支持的三种模式之一来调用它。 有什么方法可以使ASP.Net支持乐观并发?

这让我用一个新的类替换了对会话的所有调用,该类基本上执行相同的操作,但没有锁定-这很痛苦。

我想尽可能多地保留当前会话的内容(最重要的是,各个日志中的会话ID),并且代码替换量最少。 有什么办法吗? 理想情况下,我希望HttpContext.Current.Session指向我的新类,但没有ASP.Net锁定任何请求。

有没有人做过这样的事情? 似乎很奇怪,所有AJAXey MVC应用程序都存在ASP的新问题。

trans by 2020-07-13T03:32:46Z

并发-Java 8不安全:xxxFence()指令

在Java 8中,三个内存屏障指令已添加到load_storeFence()类(源):

/**
 * Ensures lack of reordering of loads before the fence
 * with loads or stores after the fence.
 */
void loadFence();

/**
 * Ensures lack of reordering of stores before the fence
 * with loads or stores after the fence.
 */
void storeFence();

/**
 * Ensures lack of reordering of loads or stores before the fence
 * with loads or stores after the fence.
 */
void fullFence();

如果我们通过以下方式定义内存屏障(我认为或多或少容易理解):

将X和Y视为需要重新排序的操作类型/类,

load_storeFence()是一个内存屏障指令,可确保在屏障启动之前,在屏障之前的所有类型X的操作都在屏障开始之前的Y类型的任何操作之前完成。

我们现在可以将load_storeFence()的障碍名称“映射”到此术语:

  • load_storeFence()变为store_loadFence();
  • load_storeFence() becomes store_loadFence();
  • load_storeFence() becomes store_loadFence();

最后,我的问题是-为什么我们没有load_storeFence()store_loadFence()store_storeFence()load_loadFence()

我的猜测是-他们并不是真正的必要,但我目前不明白为什么。 因此,我想知道不添加原因的原因。 对此的猜测也很受欢迎(但是希望这不会导致该问题成为基于观点的话题)。

提前致谢。

trans by 2020-07-10T13:58:06Z

1 2 3 4 5 6 7 8 9 下一页 共9页