关于多线程的参数问题

体会多线程的参数问题,可以用下面的代码测试,分别放开 注释1 和 注释2 部分,查看两次结果的不同之处。

注释1 部分,pageData 是一个引用对象,在其中一个线程中,引用对象的值进行的变动,它会影响到 其他的线程上。注释2部分,则根据传入的参数,构造了一个线程内临时变量。

method1 和 method2 提供了两种多线程的访问方式,并且获取多线程执行后的结果集

package com.bkc.bpmp.test;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorServiceTest
{
    public static void method2(List<Student> paramslist, Map pageData)
    {
        
        ExecutorService pool = Executors.newFixedThreadPool(30);
        List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
        for (Student stu : paramslist)
        {
            Callable c = new MyCallable(pageData, stu); // 执行任务并获取Future对象
            tasks.add(c);
        }
        
        try
        {
            // 创建多个有返回值的任务
            List<Future<Object>> list = pool.invokeAll(tasks);
            // 获取所有并发任务的运行结果
            for (Future f : list)
            {
                // 从Future对象上获取任务的返回值,并输出到控制台
                
                String string = (String)f.get();
                // System.out.println(string);
            }
            
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        // 关闭线程池
        pool.shutdown();
    }
    
    public static void method1(List<Student> paramslist, Map pageData)
    {
        
        ExecutorService pool = Executors.newFixedThreadPool(30);
        // 创建多个有返回值的任务
        List<Future> list = new ArrayList<Future>();
        for (Student stu : paramslist)
        {
            Callable c = new MyCallable(pageData, stu); // 执行任务并获取Future对象
            Future f = pool.submit(c);
            list.add(f);
        }
        // 关闭线程池
        pool.shutdown();
        // 获取所有并发任务的运行结果
        for (Future f : list)
        {
            // 从Future对象上获取任务的返回值,并输出到控制台
            try
            {
                String string = (String)f.get();
                // System.out.println(string);
            }
            catch (Exception e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    public static String formatDateTime(long timeMillis)
    {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }
    
    public static void main(String[] args)
    {
        long a = System.currentTimeMillis();
        Map pageData = new HashMap<>();
        pageData.put("dTime", "Test");
        
        List<Student> paramslist = new ArrayList<>();
        for (int i = 0; i < 50; i++)
        {
            Student student = new Student("name" + i);
            paramslist.add(student);
        }
        method1(paramslist, pageData);
        System.out.println("======耗时:" + formatDateTime(System.currentTimeMillis() - a));
    }
    
}

class MyCallable implements Callable<Object>
{
    private Map pageData;
    private Student stu;
    
    public MyCallable(Map pageData, Student stu)
    {
        this.stu = stu;
        this.pageData = pageData;
    }
    
    public void print(Map<String, String> map)
    {
        try
        {
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "===" + map.toString());
    }
    
    @Override
    public Object call()
        throws Exception
    {
        /**
         * 1
         */
        // pageData.put("tag", stu.getName());
        // print(pageData);
        
        /**
         * 2
         */
        Map<String, String> map = new HashMap<>();
        map.put("tag", stu.getName());
        map.put("dTime", (String)pageData.get("dTime"));
        print(map);
        
        return stu.getName() + pageData.get("dTime").toString();
    }
    
}

class Student
{
    String name;
    
    public Student()
    {
        super();
    }
    
    public Student(String name)
    {
        super();
        this.name = name;
    }
    
    public String getName()
    {
        return name;
    }
    
    public void setName(String name)
    {
        this.name = name;
    }
    
}
原文地址:https://www.cnblogs.com/panie2015/p/8242707.html