Java 并发/多线程何时有助于提高性能?

Java 并发/多线程何时有助于提高性能?,java,multithreading,performance,concurrency,Java,Multithreading,Performance,Concurrency,我一直计划在项目中使用并发,因为我知道它确实已经通过put增加了很多。 现在,我在多线程或并发方面的工作还不多,所以决定在实际项目中使用它之前先学习并进行简单的概念验证。 以下是我尝试过的两个例子: 1. With use of concurrency public static void main(String[] args) { System.out.println("start main "); ExecutorService es

我一直计划在项目中使用并发,因为我知道它确实已经通过put增加了很多。 现在,我在多线程或并发方面的工作还不多,所以决定在实际项目中使用它之前先学习并进行简单的概念验证。
以下是我尝试过的两个例子:

1. With use of concurrency

    public static void main(String[] args) 

    {
        System.out.println("start main ");

        ExecutorService es = Executors.newFixedThreadPool(3);
        long startTime = new Date().getTime();
        Collection<SomeComputation> collection = new ArrayList<SomeComputation>();
        for(int i=0; i< 10000; i++){
            collection.add(new SomeComputation("SomeComputation"+i));
        }
        try {
            List<Future< Boolean >> list = es.invokeAll(collection);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("\n end main "+(new Date().getTime() - startTime));
    }

2. Without use of concurrency

        public static void main(String[] args) {

          System.out.println("start main ");
          long startTime = new Date().getTime();
          Collection<SomeComputation> collection = new ArrayList<SomeComputation>();
          for(int i=0; i< 10000; i++){
          collection.add(new SomeComputation("SomeComputation"+i));
        }
        for(SomeComputation sc:collection)
        {
        sc.compute();
        }
        System.out.println("\n end main "+(new Date().getTime() - startTime));
        }

    Both share a common class

        class SomeComputation implements Callable<Boolean>
        {
            String name;
            SomeComputation(String name){this.name=name;}
            public Boolean compute()
            {
                someDumbStuff();
                return true;
            }

            public Boolean call()
            {
                someDumbStuff();
                return true;
            }

            private void someDumbStuff()
            {
                for (int i = 0;i<50000;i++)
                {
                    Integer.compare(i,i+1);
                }
                System.out.print("\n done with "+this.name);
            }
        }
1。使用并发
公共静态void main(字符串[]args)
{
System.out.println(“启动主控”);
Executors服务es=Executors.newFixedThreadPool(3);
long startTime=new Date().getTime();
集合集合=新的ArrayList();
对于(int i=0;i<10000;i++){
添加(新的SomeComputation(“SomeComputation”+i));
}
试一试{
列表>列表=es.invokeAll(集合);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“\n end main”+(new Date().getTime()-startTime));
}
2.不使用并发
公共静态void main(字符串[]args){
System.out.println(“启动主控”);
long startTime=new Date().getTime();
集合集合=新的ArrayList();
对于(int i=0;i<10000;i++){
添加(新的SomeComputation(“SomeComputation”+i));
}
用于(sc:集合)
{
sc.compute();
}
System.out.println(“\n end main”+(new Date().getTime()-startTime));
}
两者都有一个共同的阶层
类实现了可调用的计算
{
字符串名;
SomeComputation(字符串名){this.name=name;}
公共布尔计算()
{
一些愚蠢的东西();
返回true;
}
公共布尔调用()
{
一些愚蠢的东西();
返回true;
}
私有的空的东西()
{

对于(inti=0;i并发性至少有两个不同的目的:1)性能,2)代码的简单性(比如1000个web请求侦听器)

如果您的目的是提高性能,那么您无法获得比投入使用的硬件内核数量更多的加速。 (这仅在线程是CPU绑定的情况下发生。) 此外,每个线程都有很大的启动开销。
因此,如果你在一台4核机器上启动1000个线程,你不可能比4倍的加速做得更好,但与此相反,你有1000个线程的启动成本。

并发至少有两个不同的目的:1)性能,2)代码简单(比如1000个web请求侦听器)

如果您的目的是提高性能,那么您无法获得比投入使用的硬件内核数量更多的加速。 (这仅在线程是CPU绑定的情况下发生。) 此外,每个线程都有很大的启动开销。
因此,如果在一台4核机器上启动1000个线程,你不可能比4倍的加速做得更好,但与此相反,你有1000个线程的启动成本。

当线程共享相同的数据源时,需要concurrecy 因此,当一些线程使用这个源时,其他线程必须等待它 完成工作比他们有权限 所以你需要学习同步方法和bluck之类的东西 对不起,我的英语读这本书很有帮助
当线程共享相同的数据源时,需要concurrecy 因此,当一些线程使用这个源时,其他线程必须等待它 完成工作比他们有权限 所以你需要学习同步方法和bluck之类的东西 对不起,我的英语读这本书很有帮助

如其中一个答案所述,并发的一个用途是简化代码,即存在某些逻辑上并发的问题,因此无法以非并发的方式对这些问题进行建模,如生产者-消费者问题、web请求的侦听器等

除此之外,只有当并发程序能够为您节省CPU周期时,它才能提高性能,即目标是让CPU或CPU始终处于繁忙状态,而不是浪费其周期,这进一步意味着,当您的程序在非CPU任务(如等待数据)中忙碌时,您可以让CPU做一些有用的事情isk I/O、等待锁定、睡眠、GUI应用程序用户等待等—这些时间只是将时间添加到总程序运行时间中

所以问题是,当你的程序不使用时,你的CPU在做什么?我能在这段时间内完成我程序的一部分并将等待的部分分离到另一个线程中吗?现在,大多数现代系统都是多处理器和多核系统,如果程序不是并发的,会进一步导致浪费

您编写的示例是在内存中执行所有处理,而不进入任何等待状态,因此在设置线程和上下文切换时,您不会看到太多收益,而只看到损失

尝试通过点击一个数据库来衡量性能,获取100万条记录,处理这些记录,然后再次将这些记录保存到数据库中。以并行方式一次按顺序、小批量执行,这样您就可以注意到性能差异,因为数据库操作是磁盘密集型的,当您读取或写入数据库时,实际上是在执行磁盘操作在此期间,I/O和CPU可以自由地浪费其周期

在我看来,好的并发候选任务是长时间运行的任务,涉及上面提到的等待操作之一,否则您看不到太多好处。需要一些后台任务的程序也是好的并发候选任务

并发性不应与CPU的多任务处理混淆,即当您在同一CPU上同时运行不同的程序时


希望它能有所帮助!!

正如其中一个答案中提到的,并发的一个用途是代码的简单性,即有一些