Потоки в Java

Материал из BiTel WiKi

Перейти к: навигация, поиск

Ускорение задачи путем разбиения на несколько потоков

Актуально для многопроцессорных (многоядерных) систем.

public class Test
{
    public static void main( String[] args )
    {
        final int TASK_COUNT = 1000;
        final int NUM_COUNT = 3000000;
 
        int[] sums = new int[TASK_COUNT];
        //
        long timeStart = System.currentTimeMillis();        
 
        for( int i = 0; i < TASK_COUNT; i++ )
        {
            for( int j = 1; j <= NUM_COUNT; j++ )
            {
                sums[i] += j;
            }
        }       
 
        long timeEnd = System.currentTimeMillis();
        System.out.println( "Full time: " + (timeEnd - timeStart) );
    }
}


import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
 
 
public class Test
{
    public static void main( String[] args )
    {
        final int TASK_COUNT = 1000;
        final int NUM_COUNT = 3000000;
 
        final int[] sums = new int[TASK_COUNT];
        //
        long timeStart = System.currentTimeMillis();        
 
        final ThreadPoolExecutor pool = new ThreadPoolExecutor( 2, 2, 0L, 
                                                                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>() );
        final AtomicInteger taskCount = new AtomicInteger();
 
        for( int i = 0; i < TASK_COUNT; i++ )
        {
            final int iCurrent = i;
 
            pool.execute( new Thread()
            {
                @Override
                public void run()
                {
                    for( int j = 1; j <= NUM_COUNT; j++ )
                    {
                        sums[iCurrent] += j;
                    }
                    taskCount.decrementAndGet();
                }
            });
 
            taskCount.incrementAndGet();
        }
 
        while( taskCount.get() != 0 )
        {
            try 
            {
                Thread.sleep( 500 );
            } 
            catch (Exception e) 
            {}            
        }
 
        long timeEnd = System.currentTimeMillis();
        System.out.println( "Full time: " + (timeEnd - timeStart) );
    }
}

Конкретно этот пример покажет, вполне возможно, падение производительности. Однако оптимизированные по подобной методике тяжелые процессы, которые могут быть разбиты на множество задач, показывают хороший рост производительности.

Личные инструменты