对象深拷贝 多线程 1、List使用序列化实现深拷贝 public static List deepCopy(List src) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new Ob
1、List使用序列化实现深拷贝 public staticList deepCopy(List src) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(byteIn); @SuppressWarnings("unchecked") List dest = (List ) in.readObject(); return dest; } List destList=deepCopy(srcList); //调用该方法 2、多线程Executors Executors 提供了一系列工厂方法用于创先线程池 a、newCachedThreadPool() 缓存型池子,先查看池中有没有以前建立的线程,如果有,就 reuse 如果没有,就建一个新的线程加入池中,通常用于执行一些生存期很短的异步型任务 b、newFixedThreadPool(int) 任意时间点,最多只能有固定数目的活动线程存在,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程中某个线程终止直接被移出池子 FixedThreadPool 多数针对一些很稳定很固定的正规并发线程,多用于服务器。 c、newScheduledThreadPool(int) 调度型线程池,这个池子里的线程可以按 schedule 依次 delay 执行,或周期执行 d、SingleThreadExecutor() 单例线程,任意时间池中只能有一个线程,用的是和 cache 池和 fixed 池相同的底层池,但线程数目是 1-1,0 秒 IDLE(无 IDLE) CachedTheadPool 在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它是合理的 Executor 的首选 示例: a、Executor 执行 Runnable 任务 public class TestCachedThreadPool{ public static void main(String[] args){ ExecutorService executorService = Executors.newCachedThreadPool(); //ExecutorService executorService = Executors.newFixedThreadPool(5); //ExecutorService executorService = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i++){ executorService.execute(new TestRunnable()); System.out.println("************* a" + i + " *************"); } executorService.shutdown(); } } class TestRunnable implements Runnable{ public void run(){ System.out.println(Thread.currentThread().getName() + "线程被调用了。"); } } b、Executor 执行 Callable 任务 public class CallableDemo{ public static void main(String[] args){ ExecutorService executorService = Executors.newCachedThreadPool(); List > resultList = new ArrayList >(); //创建10个任务并执行 for (int i = 0; i < 10; i++){ //使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中 Future future = executorService.submit(new TaskWithResult(i)); //将任务执行结果存储到List中 resultList.add(future); } //遍历任务的结果 for (Future fs : resultList){ try{ while(!fs.isDone);//Future返回如果没有完成,则一直循环等待,直到Future返回完成 System.out.println(fs.get()); //打印各个线程(任务)执行的结果 }catch(InterruptedException e){ e.printStackTrace(); }catch(ExecutionException e){ e.printStackTrace(); }finally{ //启动一次顺序关闭,执行以前提交的任务,但不接受新任务 executorService.shutdown(); } } } } class TaskWithResult implements Callable { private int id; public TaskWithResult(int id){ this.id = id; } /** * 任务的具体过程,一旦任务传给ExecutorService的submit方法, * 则该方法自动在一个线程上执行 */ public String call() throws Exception { System.out.println("call()方法被自动调用!!! " + Thread.currentThread().getName()); //该返回结果将被Future的get方法得到 return "call()方法被自动调用,任务返回的结果是:" + id + " " + Thread.currentThread().getName(); } } c、自定义线程池 import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadPoolTest{ public static void main(String[] args){ //创建等待队列 BlockingQueue bqueue = new ArrayBlockingQueue (20); //创建线程池,池中保存的线程数为3,允许的最大线程数为5 ThreadPoolExecutor pool = new ThreadPoolExecutor(3,5,50,TimeUnit.MILLISECONDS,bqueue); //corePoolSize:线程池中所保存的核心线程数,包括空闲线程。 //maximumPoolSize:池中允许的最大线程数。 //keepAliveTime:线程池中的空闲线程所能持续的最长时间。 //unit:持续时间的单位。 //workQueue:任务执行前保存任务的队列,仅保存由 execute 方法提交的 Runnable 任务。 //创建七个任务 Runnable t1 = new MyThread(); Runnable t2 = new MyThread(); Runnable t3 = new MyThread(); Runnable t4 = new MyThread(); Runnable t5 = new MyThread(); Runnable t6 = new MyThread(); Runnable t7 = new MyThread(); //每个任务会在一个线程上执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); pool.execute(t6); pool.execute(t7); //关闭线程池 pool.shutdown(); } } class MyThread implements Runnable{ @Override public void run(){ System.out.println(Thread.currentThread().getName() + "正在执行。。。"); try{ Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } } } 3、其它Java工具 a、mockito 简单地说就是对测试的类所依赖的其他类和对象,进行mock - 构建它们的一个假的对象, 定义这些假对象上的行为,然后提供给被测试对象使用。被测试对象像使用真的对象一样使用它们。 用这种方式,我们可以把测试的目标限定于被测试对象本身,就如同在被测试对象周围做了一个划断, 形成了一个尽量小的被测试目标。 b、pagehelper mybits的分页插件,目前不支持条件查询,但修改过后的PageHelper插件,可以支持条件查询,相对来说就比较强大了 c、quartz Java任务调度框架,企业级应用的功能,让job和trigger运行在Terracotta客户端中,而不是随意选择的客户端 try { // Grab the Scheduler instance from the Factory Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // and start it off scheduler.start(); scheduler.shutdown(); } catch (SchedulerException se) { se.printStackTrace(); } //一旦你通过StdSchedulerFactory.getDefaultScheduler()获得了一个调度器,你的程序会一直运行,直到调用scheduler.shutdown()方法 d、bsh Beanshell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性。 BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。利用的原理当然是java的反射。 import bsh.Interpreter; Interpreter i = new Interpreter(); // Construct an interpreter i.set("foo", 5); // Set variables i.set("date", new Date() ); Date date = (Date)i.get("date"); // retrieve a variable // Eval a statement and get the result i.eval("bar = foo*10"); System.out.println( i.get("bar") ); // Source an external script file i.source("somefile.bsh"); e、Logback是由log4j创始人设计的又一个开源日志组件 Logback是要与SLF4J结合起来用,更快的实现 Logback的内核重写了,在一些关键执行路径上性能提升10倍以上 Logback-classic非常自然实现了SLF4j,自动重新加载配置文件 ,配置文件可以处理不同的情况 开发人员经常需要判断不同的Logback配置文件在不同的环境下(开发,测试,生产) 堆栈树带有包版本,自动去除旧的日志文件,Filters(过滤器),自动压缩已经打出来的log f、cas-client-core 单点登录(Single sign-on,简称为 SSO),是目前比较流行的企业业务整合的解决方案之一。其简单定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 类似的,用户只需要执行一次退出操作就可以终止对所有相关应用系统的访问 g、commons-codec Apache开源组织提供的用于摘要运算、编码的包, 在该包中主要分为四类加密:BinaryEncoders、DigestEncoders、LanguageEncoders、NetworkEncoders 包括Base64、SHA,MD5摘要运算、URLCodec等。 h、commons-net Apache commons net 项目中封装了各种网络协议的客户端,支持的协议包括:FTP,NNTP SMTP,POP3Telnet,TFTP,Finger,Whois,rexec/rcmd/rlogin,Time (rdate) andDaytime, Echo,Discard,NTP/SNTP i、commons-compress Compress是ApacheCommons提供压缩、解压缩文件的类库, 可以操作ar, cpio, Unix dump, tar, zip,gzip, XZ, Pack200 and bzip2格式的文件,功能比较强大 j、commons-lang3 供了高度可重用静态的工具方法,主要是对java.lang类的一些补充, 配置文件可以处理不同的情况,DateFormatUtils : 提供格式化日期和时间的功能及相关常量, StopWatch : 提供一套方便的计时器的API。 DateUtils : 在Calendar和Date的基础上提供更方便的访问, DurationFormatUtils : 提供格式化时间跨度的功能及相关常量, FastDateFormat : 为java.text.SimpleDateFormat提供一个的线程安全的替代类, FastDateParser : 为java.text.SimpleDateFormat提供一个的线程安全的替代类, FastDatePrinter : 为java.text.SimpleDateFormat提供一个的线程安全的替代类 4、线程计数器,线程等待执行 public void countDownLatch() throws InterruptedException { long start = System.currentTimeMillis(); int threadNum = 10; final CountDownLatch countDownLatch = new CountDownLatch(threadNum); for (int i = 0;i < threadNum;i++){ new Thread(new Runnable() { @Override public void run() { System.out.println(threadNum); countDownLatch.countDown(); } }).start(); } countDownLatch.await(); System.out.println(System.currentTimeMillis()-start); } org.jasig.cas cas-client-core3.2.5