java遍历目录及子目录下的文件

java遍历目录及子目录下的文件 http://blog.csdn.net/suncheng_hong/article/details/1671632 package com.daacc.common; import java.io.File; public class FileManager { String dir = ""; String temp = ""; public String[] serachFiles(String dir) { File root = new File(dir); File[] filesOrDirs = root.listFiles(); String[] result = new String[10]; for (int i = 0; i < filesOrDirs.length; i++) { if (filesOrDirs[i].isDirectory()) { serachFiles(filesOrDirs[i].getAbsolutePath()); } else { result[i] = filesOrDirs[i].getName(); temp += filesOrDirs[i].getName() + ","; } } return temp.split(","); } /** * @param args */ public static void main(String[] args) { FileManager fm = new FileManager(); String[] files = fm.serachFiles("D:/abc"); for (int i = 0; i < files.length; i++) { System.out.println("files[" + i + "]" + files[i]); } } }

2012-09-04 · 1 min · 107 words · -

Parasoft Jtest

Parasoft Jtest http://www.parasoft.com/jsp/products/jtest.jsp> Parasoft Jtest is an integrated Development Testing solution for automating a broad range of practices proven to improve development team productivity and software quality. It focuses on practices for validating Java code and applications, and it seamlessly integrates with Parasoft SOAtest to enable end-to-end functional and load testing of today’s complex, distributed applications and transactions. Jtest facilitates: Static analysis — static code analysis, data flow static analysis, and metrics analysis Peer code review process automation—preparation, notification, and tracking Unit testing — JUnit and Cactus test creation, execution, optimization, and maintenance Runtime error detection — race conditions, exceptions, resource & memory leaks, security attack vulnerabilities, and more This provides teams a practical way to prevent, expose, and correct errors in order to ensure that their Java code works as expected. To promote rapid remediation, each problem detected is prioritized based on configurable severity assignments, automatically assigned to the developer who wrote the related code, and distributed to his or her IDE with direct links to the problematic code and a description of how to fix it. ...

2012-09-03 · 2 min · 232 words · -

IDEA JavaDoc

IDEA JavaDoc http://www.intellij.org.cn/bbs/viewtopic.php?t=1817&start=0 在类或者函数前输入 /** 然后回车,就可以生成啦。 Javadoc Sync plugin可以快速生成所有的注释,使用稍微麻烦点,步骤如下: 打开设置面板,选择inspection,然后找到"javadoc issues",选择相应的配置项 回到编辑窗口,会有警告提示,将光标置于类名上,按下Alt+Enter,选择生成javadoc就可以啦。 如果你想设置生成的javadoc内容,设置面板有一个javadoc sync settings,进行设置即可。

2012-09-02 · 1 min · 15 words · -

JAVA读文本文件

JAVA读文本文件 一行一行的读~~ public static void main(String[] args) throws Exception { FileReader reader = new FileReader("D:\url.txt"); BufferedReader br = new BufferedReader(reader); String s1 = null; while((s1 = br.readLine()) != null) { System.out.println(s1); } br.close(); reader.close(); }

2012-09-02 · 1 min · 35 words · -

SuperCSV

SuperCSV Super CSV是一个速度奇快、免费跨平台的 CVS 格式数据的读写库,可以方便的处理对象、Map、列表的读写操作,以及自动化的类型转换和数据检查功能。 InputStreamReader freader = new InputStreamReader(new FileInputStream( new File("csv/test1.csv")), "GB2312"); ICsvBeanReader reader = new CsvBeanReader(freader, CsvPreference.EXCEL_PREFERENCE); //获取头部信息 String[] headers = reader.getCSVHeader(true); //获取数据部分 UserBean bean = null; while ((bean = reader.read(UserBean.class, headers, UserBean.readProcessors)) != null) { System.out.print(bean.getName() + "t"); System.out.print(bean.getAge() + "t"); System.out.print(bean.getBirthday() + "t"); System.out.println(bean.getAddress()); } java csv: Commons CSV (Sandbox) Skife CSV opencsv GenJava-CSV Super Csv JavaCSV CSVBeans

2012-08-28 · 1 min · 63 words · -

ArrayBlockingQueue

ArrayBlockingQueue ArrayBlockingQueue 是一个基于数组的阻塞队列实现,此队列按 FIFO (先进先出) 原则对元素进行排序, 在 ArrayBlockingQueue 内部,维护了一个定长数组,以便缓存队列中的数据对象,这是一个常用的阻塞队列,除了一个定长数组外,ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。 ArrayBlockingQueue 在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于 LinkedBlockingQueue, 按照实现原理来分析 ArrayBlockingQueue 完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。Doug Lea 之所以没这样去做,也许是因为 ArrayBlockingQueue 的数据写入和获取操作已经足够轻巧,以至于引入独立的锁机制,除了给代码带来额外的复杂性外,其在性能上完全占不到任何便宜。 ArrayBlockingQueue 和 LinkedBlockingQueue 间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的 Node 对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于 GC 的影响还是存在一定的区别。而在创建 ArrayBlockingQueue 时,我们还可以控制对象的内部锁是否采用公平锁,默认采用非公平锁。 队列的头部是在队列中存在时间最长的元素。队列的尾部是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列检索操作则是从队列头部开始获得元素。 这是一个典型的 “有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致放入操作受阻塞;试图从空队列中检索元素将导致类似阻塞。 此类支持对等待的生产者线程和使用者线程进行排序的可选公平策略。默认情况下,不保证是这种排序。然而,通过将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了"不平衡性"。 ArrayBlockingQueue 在构造时需要指定容量,并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理 (其实就是通过将 ReentrantLock 设置为 true 来达到这种公平性的: 即等待时间最长的线程会先操作) 。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队列,此队列按 FIFO (先进先出) 原则对元素进行排序。 PriorityBlockingQueue PriorityBlockingQueue 是一个带优先级的队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限 (看了一下源码,PriorityBlockingQueue 是对 PriorityQueue 的再次包装,是基于堆数据结构的,而 PriorityQueue 是没有容量限制的,与ArrayList一样,所以在优先阻塞队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError) ,但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元素要具有比较能力。 最后,DelayQueue (基于PriorityQueue来实现的) 是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。 下面是延迟接口: ...

2012-08-26 · 2 min · 366 words · -

Java 线程池, thread pool, Executors, ThreadPoolExecutor

Java 线程池, thread pool, Executors, ThreadPoolExecutor Executors ThreadPoolExecutor ExecutorService 在 Java 1.5 引入 ExecutorService 之后,基本上已经不建议直接创建 Thread 对象,而是统一使用 ExecutorService。毕竟从接口的易用程度上来说 ExecutorService 就远胜于原始的 Thread,更不用提 java.util.concurrent 提供的数种线程池,Future 类,Lock 类等各种便利工具。 在操作系统中,线程是一个非常重要的资源,频繁创建和销毁线程会降低系统性能。Java 线程池原理类似于数据库连接池,目的就是帮助我们实现线程复用,减少频繁创建和销毁线程。ThreadPoolExecutor Executors Executors 提供了一些创建线程池的工具方法。 ExecutorService es = Executors.newSingleThreadExecutor() 源码实现: new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()) corePoolSize 和maximumPoolSize都为1,也就是创建了一个固定大小是1的线程池,workQueue是 new LinkedBlockingQueue<Runnable>() 也就是队列的大小是Integer.MAX_VALUE,可以认为是队列的大小不限制。 由此可以得出通过该方法创建的线程池,每次只能同时运行一个线程,当有多个任务同时提交时,那也要一个一个排队执行。 Executors.newFixedThreadPool(int nThreads) 源码实现: new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()) 类似Executors.newSingleThreadExecutor()也是创建了一个固定大小的线程池,但是可以指定同时运行的线程数量为nThreads。 Executors.newCachedThreadPool() 源码实现: new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()) ...

2012-08-26 · 4 min · 704 words · -

Java 反编译

Java 反编译 Java Decompiler “Java Decompiler”, 由 Pavel Kouznetsov开发,目前最新版本为0.2.5. 它由 C++开发,并且官方可以下载windows、linux和苹果Mac Os三个平台的可执行程序。 http://jd.benow.ca/ http://www.oschina.net/p/java+decompiler DJ Java Decompiler(不免费) DJ Java Decompiler 是个反编译的工具,可以将编译过的 CLASS 文件编译还原成为 Java 原始文件,并且不需要额外安装 JVM (Java Virtual Machine) 或是JDK 的工具模组即可使用。不单如此,它也兼具有 Java 程序编辑工具的角色,提供一些辅助功能便于程序撰写与修改。 DJ Java Decompiler 在 Windows 95、Windows 98、Windows 2000、Windows XP、Windows 2003、Windows Vista、 Windows 7等多种平台上均可以运行的 Java 反编译器和汇编器。DJ Java Decompiler 能够反复编译复杂的 Java 小程序和二进制文件,生产出准确的源代码。它不仅是 Java 反编译器和汇编器,也是一个功能齐全的使用有着着色语法的图形用户界面的 Java 编辑器。 这款软件十分适合用来学习编程,而且它能够让用户保存、打印、编辑和编译生成的 Java 代码。 另外,DJ Java Decompiler 是一个独立的 windows 应用程序,它不要求安装Java,所以运行使用相当方便,大家不妨试一下。 个人觉得比较好的功能有: 可以直接打开jar 档, 查看jar 包里原文件 ...

2012-08-24 · 1 min · 75 words · -

ArrayList Capacity

ArrayList Capacity http://topic.csdn.net/t/20061223/10/5250896.html 任何一个 ArrayList 对象都有一个 capacity 属性,用来指示该 ArrayList 的容量,用"容量"这个词容易引起像本贴楼主那样的误解,我觉得用"容纳能力"比较贴切。 我们知道ArrayList的内部是采用数组来存储元素的,由于java数组都是定长的,所以这个数组的大小一定是固定的,这个大小就是capacity。我们可以肯定capacity一定是大于或等于ArrayList的size,那么当size不断增加到了要超过capacity的时候,ArrayList就不得不重新创建新的capacity来容纳更多的元素,这时需要首先建立一个更长的数组,将原来的数组中的元素复制到新数组中,再删除原来的数组。可见当ArrayList越来越大时,这种操作的消耗也是越来越大的。 为了减少这种不必要的重建capacity的操作,当我们能肯定ArrayList大致有多大 (或者至少会有多大) 时,我们可以先让ArrayList把capacity设为我们期望的大小,以避免多余的数组重建。 假设ArrayList自动把capacity设为10,每次重建时将长度递增原来的三分之二,那么当我们需要大约存储50个元素到ArrayList中时,就会大约需要重建数组4次,分别是在增加第11、第17、第26、第39个元素的时候进行的。如果我们一开始就让ArrayList的capacity为50,那么不需要任何数组重建就能完成所有插入操作了。 java允许我们在构造ArrayList的同时指定capacity,如new ArrayList(50),也允许在以后将它设得更大,而增大capacity就是使用ensureCapacity()方法。注意: capacity只能比原来的更大,而不能比原来的更小,否则java会忽略该操作。ArrayList的初始默认capacity为10,所以给capacity指定小于10的整数是毫无意义的。 最后说说ArrayList的size,前面说过,size一定小于等于capactiy,而且更重要的是,访问超过size的位置将抛出异常,尽管这个位置可能没有超过capacity。ensureCapacity()只可能增加capacity,而不会对size有任何影响。要增加size,只能用add()方法。 https://blog.csdn.net/vandavidchou/article/details/104306445

2012-08-20 · 1 min · 20 words · -

JAVA 正则表达式 分组与捕获

JAVA 正则表达式 分组与捕获 import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Fenzhu { public static void main(String[] args) { Pattern p = Pattern.compile("(/d{3,5})([a-z]{2})"); String s = "123aa-34345bb-234cc-00"; Matcher m = p.matcher(s); while(m.find()) { System.out.println("m.group():"+m.group()); //打印所有 System.out.println("m.group(1):"+m.group(1)); //打印数字的 System.out.println("m.group(2):"+m.group(2)); //打印字母的 System.out.println(); } System.out.println("捕获个数:groupCount()="+m.groupCount()); } } 1 概述 1.1 什么是捕获组 捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部。 捕获组有两种形式,一种是普通捕获组,另一种是命名捕获组,通常所说的捕获组指的是普通捕获组。语法如下: 普通捕获组: (Expression) 命名捕获组: (?Expression) 普通捕获组在大多数支持正则表达式的语言或工具中都是支持的,而命名捕获组目前只有.NET、PHP、Python等部分语言支持,据说Java会在7.0中提供对这一特性的支持。上面给出的命名捕获组的语法是.NET中的语法,另外在.NET中使用(?’name’Expression)与使用(?Expression)是等价的。在PHP和Python中命名捕获组语法为: (?PExpression)。 ...

2012-08-19 · 3 min · 574 words · -

java正则表达式的中的问号

java正则表达式的中的问号 java正则表达式中的 ? 是惰性匹配,具体的看下面的例子: Pattern pattern = Pattern.compile("<.*>"); Matcher matcher =pattern.matcher("主页"); System.out.println(matcher.replaceAll("")); 将输出空,因为没有加问号,此时进行的是最长匹配(贪婪匹配) 可以做如果更改 Pattern pattern = Pattern.compile("<.*>"); Matcher matcher =pattern.matcher("主页[color=red]</a[/color]"); System.out.println(matcher.replaceAll("")); 将输出: 主页</a 如果把程序修改为: Pattern pattern = Pattern.compile("<.*?>"); Matcher matcher =pattern.matcher("主页"); System.out.println(matcher.replaceAll("")); 将输出: 主页 不加 ? 表示贪婪,加 ? 表示勉强,区别如下: 勉强是从左边一个一个地吃直到匹配为止,不加 ?的是一口吃掉整个字符串,然后从最后一个一个地吐出来直到匹配为止 字符串 a=====b=====b=== a.*b 将匹配满足条件最长的字符串 a=====b=====b 工作方式: 首先将: a=====b=====b=== 全部吃掉,从右边一个一个地吐出来 1. a=====b=====b=== 不匹配,吐出一字符 a=====b=====b== 不匹配,再吐出一字符 a=====b=====b= 不匹配,再吐出一字符 a=====b=====b 匹配了,结束。如果再不匹配继续吐,直到没有字符了,匹配失败 a.*? 将匹配满足条件最短的字符串 a=====b 工作方式: 从左边一个一个地吃掉字符 ...

2012-08-19 · 1 min · 83 words · -

Java正则表达式

Java正则表达式 大写字母和数字组成的10个字符 private static final Pattern pattern = Pattern.compile("([A-Z]|[0-9]){10}"); pattern.matcher("abcd1234567").matches(); 3位数字 d{3} 众所周知,在程序开发中,难免会遇到需要匹配、查找、替换、判断字符串的情况发生,而这些情况有时又比较复杂,如果用纯编码方式解决,往往会浪费程序员的时间及精力。因此,学习及使用正则表达式,便成了解决这一矛盾的主要手段。 大家都知道,正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符 (例如字符a到z) 以及特殊字符 (元字符) 组成的文字模式,它 用以描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 自从jdk1.4推出java.util.regex包,就为我们提供了很好的JAVA正则表达式应用平台。因为正则表达式是一个很庞杂的体系,所以我仅例举些入门的概念,更多的请参阅相关书籍及自行摸索。 // 反斜杠 /t 间隔 (’/u0009’) /n 换行 (’/u000A’) /r 回车 (’/u000D’) /d 数字 等价于[0-9] /D 非数字 等价于[^0-9] /s 空白符号 [/t/n/x0B/f/r] /S 非空白符号 [^/t/n/x0B/f/r] /w 单独字符 [a-zA-Z_0-9] /W 非单独字符 [^a-zA-Z_0-9] /f 换页符 /e Escape /b 一个单词的边界 /B 一个非单词的边界 /G 前一个匹配的结束 ^为限制开头 ^java 条件限制为以Java为开头字符 $为限制结尾 java$ 条件限制为以java为结尾字符 . 条件限制除/n以外任意一个单独字符 java.. 条件限制为java后除换行外任意两个字符 加入特定限制条件「[]」 [a-z] 条件限制在小写a to z范围中一个字符 [A-Z] 条件限制在大写A to Z范围中一个字符 [a-zA-Z] 条件限制在小写a to z或大写A to Z范围中一个字符 [0-9] 条件限制在小写0 to 9范围中一个字符 [0-9a-z] 条件限制在小写0 to 9或a to z范围中一个字符 [0-9[a-z]] 条件限制在小写0 to 9或a to z范围中一个字符(交集) ...

2012-08-19 · 3 min · 538 words · -

pacakge-info.java

pacakge-info.java http://strong-life-126-com.iteye.com/blog/806246 翻看以前的笔记,看到一个特殊的java文件: pacakge-info.java,虽然有记录,但是不全,就尝试着追踪一下该问题, 分享一下流水账式的结果。 首先,它不能随便被创建。在Eclipse中, package-info文件不能随便被创建,会报"Type name is notvalid"错误,类名无效,Java变量定义规范是: 字母、数字、下划线,还有那个不怎么常用的$符号 (顺带说下,Java是支持中文名称的变量,习惯挑战的同学可以尝试下,分享一下这方面的经验) ,这个中划线可不再之列,那怎么创建这个文件呢? 很简单,用记事本创建一个,然后拷贝进去再改一下就成了,更直接的办法就是从别的项目中拷贝过来一个,这更方便。 其次,服务的对象很特殊。一个类是一类或一组事物的描述,比如Dog这个类,就是描述旺财的,那package-info这个类是描述啥的呢?它总要有一个被描述或被陈述的对象,它是描述和记录本包信息。 最后,类不能带有public、private访问权限。package-info.java再怎么特殊,也是一个类文件,也会被编译成package-info.class,但是在package-info.java中只能声明默认访问权限的类,也就是友好类。 其实还有几个特殊的地方,比如不可以继承,没有接口,没有类间关系 (关联、组合、聚合等等) 等。 这个文件的特殊性说完了,那再说说它有什么作用,它有三个作用: 为标注在包上Annotation提供便利; 声明友好类和包常量; 提供包的整体注释说明。 我们来建立一个项目演示这三个作用,建立一个package-info的Java Project,在com.company包三个类:package-info.java 是我们重点关注的,PkgAnnotation.java是一个标注在包上的注解定义,Client.java模拟业务操作类。其结构如下图: 为标注在包上Annotation提供便利 首先定义一个包类型的注解,它只能放置的一个包上: Java代码 /** 定义只能标注在package上的注解 */ @Target(ElementType.PACKAGE) @Retention(RetentionPolicy.RUNTIME) public @interface PkgAnnotation { } 再定义一个package-info类,这个是一个特殊的类,先看代码: Java代码 @PkgAnnotation package com.company; 很简单,就这么个文件,里面啥都没有,就这两句话,没有class类,没有常变量声明。接着写一个模拟交易类,代码如下: Java代码 public class Client { public static void main(String[] args) { //可以通过I/O操作或配置项获得包名 String pkgName = “com.company”; Package pkg = Package.getPackage(pkgName); //获得包上的注解 Annotation[] annotations = pkg.getAnnotations(); //遍历注解数组 for(Annotation an:annotations){ if(an instanceof PkgAnnotation){ ...

2012-08-15 · 1 min · 156 words · -

java, break/continue

java, break/continue 使用break 退出循环 可以使用break 语句直接强行退出循环,忽略循环体中任何其他语句和循环条件测试。在循环中遇到break语句时,循环被终止,程序控制在循环后面语句重新开始。例如 如果for 循环被设计为从 0执行到99,然后输出0到99这些数字,但是当i等于10时,break语句终止程序。所以程序只会输出0到10。 在一系列嵌套循环中使用break 语句时,它将仅仅终止最里面循环。 而continue则停止执行当前的反复,然后退回循环起始和,开始新的反复。continue 用于跳过循环体中的一部分语句,也就是不执行这部分语句 return语句用来明确地从一个方法返回。也就是,return 语句使程序控制返回到调用它方法。因此,将它分类为跳转语句。尽管对return 语句详细讨论在第 7 章开始,这里对其作简要地介绍。在一个方法任何时间,return 语句可被用来使正在执行分支程序返回到调用它方法。下面例子说明这一点。下例中,由于是Java 运行系统调用main() ,因此,return语句使程序执行返回到Java 运行系统。 http://java.chinaitlab.com/base/799194.html

2012-07-08 · 1 min · 23 words · -

ReentrantLock,互斥锁,重入锁

ReentrantLock,互斥锁,重入锁 在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确保在某一时刻,方法内只允许有一个线程。 synchronized 采用 synchronized 修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个 monitor (锁标记),当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。 这里就使用同步机制获取互斥锁的情况,进行几点说明: 如果同一个方法内同时有两个或更多线程,则每个线程有自己的局部变量拷贝。 类的每个实例都有自己的对象级别锁。当一个线程访问实例对象中的 synchronized 同步代码块或同步方法时,该线程便获取了该实例的对象级别锁,其他线程这时如果要访问 synchronized 同步代码块或同步方法,便需要阻塞等待,直到前面的线程从同步代码块或方法中退出,释放掉了该对象级别锁。 访问同一个类的不同实例对象中的同步代码块,不存在阻塞等待获取对象锁的问题,因为它们获取的是各自实例的对象级别锁,相互之间没有影响。 持有一个对象级别锁不会阻止该线程被交换出来,也不会阻塞其他线程访问同一示例对象中的非synchronized代码。当一个线程A持有一个对象级别锁 (即进入了 synchronized 修饰的代码块或方法中) 时,线程也有可能被交换出去,此时线程B有可能获取执行该对象中代码的时间,但它只能执行非同步代码 (没有用synchronized修饰) ,当执行到同步代码时,便会被阻塞,此时可能线程规划器又让A线程运行,A线程继续持有对象级别锁,当A线程退出同步代码时 (即释放了对象级别锁) ,如果B线程此时再运行,便会获得该对象级别锁,从而执行synchronized中的代码。 持有对象级别锁的线程会让其他线程阻塞在所有的 synchronized 代码外。例如,在一个类中有三个synchronized方法 a,b,c,当线程A正在执行一个实例对象M中的方法 a 时,它便获得了该对象级别锁,那么其他的线程在执行同一实例对象 (即对象M) 中的代码时,便会在所有的 synchronized 方法处阻塞,即在方法 a,b,c处都要被阻塞,等线程A释放掉对象级别锁时,其他的线程才可以去执行方法a,b或者c中的代码,从而获得该对象级别锁。 使用 synchronized (obj) 同步语句块,可以获取指定对象上的对象级别锁。obj为对象的引用,如果获取了obj对象上的对象级别锁,在并发访问obj对象时时,便会在其synchronized代码处阻塞等待,直到获取到该obj对象的对象级别锁。当obj为 this 时,便是获取当前对象的对象级别锁。 类级别锁被特定类的所有示例共享,它用于控制对static成员变量以及static方法的并发访问。具体用法与对象级别锁相似。 互斥是实现同步的一种手段,临界区、互斥量和信号量都是主要的互斥实现方式. synchronized 关键字经过编译后,会在同步块的前后分别形成 monitorenter 和 monitorexit 这两个字节码指令。根据虚拟机规范的要求,在执行 monitorenter 指令时,首先要尝试获取对象的锁,如果获得了锁,把锁的计数器加1,相应地,在执行 monitorexit 指令时会将锁计数器减1,当计数器为0时,锁便被释放了。由于synchronized 同步块对同一个线程是可重入的,因此一个线程可以多次获得同一个对象的互斥锁,同样,要释放相应次数的该互斥锁,才能最终释放掉该锁。 synchronized 是非公平锁 (TODO: 需要测试,没重现成功…) https://blog.csdn.net/FU250/article/details/106640613 ReentrantLock ReentrantLock 是一个可重入的互斥锁,又被称为"独占锁"。ReentrantLock 的实现不仅可以替代隐式的 synchronized 关键字,而且能够提供超过关键字本身的多种功能。 而锁的名字也是说明了这个锁具备了重复进入的可能,也就是说能够让当前线程多次的进行对锁的获取操作,这样的最大次数限制是 Integer.MAX_VALUE,约 21 亿次左右。 ...

2012-07-08 · 5 min · 940 words · -

CopyOnWriteArrayList

CopyOnWriteArrayList http://www.cnblogs.com/sunwei2012/archive/2010/10/08/1845656.html 除了加锁外,还有一种方式可以防止并发修改异常,就是读写分离技术 (不是数据库上的) 。 先回顾一下一个常识: JAVA中"=“操作只是将引用和某个对象关联,假如同时有一个线程将引用指向另外一个对象,一个线程获取这个引用指向的对象,那么他们之间不会发生ConcurrentModificationException,他们是在虚拟机层面阻塞的,而且速度非常快,几乎不需要CPU时间。 JAVA中两个不同的引用指向同一个对象,当第一个引用指向另外一个对象时,第二个引用还将保持原来的对象。 基于上面这个常识,我们再来探讨下面这个问题: 在CopyOnWriteArrayList里处理写操作 (包括add、remove、set等) 是先将原始的数据通过JDK1.6的Arrays.copyof()来生成一份新的数组 然后在新的数据对象上进行写,写完后再将原来的引用指向到当前这个数据对象 (这里应用了常识1) ,这样保证了每次写都是在新的对象上 (因为要保证写的一致性,这里要对各种写操作要加一把锁,JDK1.6在这里用了重入锁) , 然后读的时候就是在引用的当前对象上进行读 (包括get,iterator等) ,不存在加锁和阻塞,针对iterator使用了一个叫COWIterator的阉割版迭代器,因为不支持写操作,当获取CopyOnWriteArrayList的迭代器时,是将迭代器里的数据引用指向当前引用指向的数据对象,无论未来发生什么写操作,都不会再更改迭代器里的数据对象引用,所以迭代器也很安全 (这里应用了常识2) 。 CopyOnWriteArrayList中写操作需要大面积复制数组,所以性能肯定很差,但是读操作因为操作的对象和写操作不是同一个对象,读之间也不需要加锁,读和写之间的同步处理只是在写完后通过一个简单的”=“将引用指向新的数组对象上来,这个几乎不需要时间,这样读操作就很快很安全,适合在多线程里使用,绝对不会发生ConcurrentModificationException,所以最后得出结论: CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。

2012-07-08 · 1 min · 24 words · -

ConcurrentHashMap/CopyOnWriteArrayList

ConcurrentHashMap/CopyOnWriteArrayList ConcurrentHashMap, CopyOnWriteArrayList 并发集合类 ConcurrentHashMap 和 CopyOnWriteArrayList(转) 在Java类库中出现的第一个关联的集合类是 Hashtable ,它是JDK 1.0的一部分。 Hashtable 提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的―― Hashtable 的所有方法都是同步的。此时,无竞争的同步会导致可观的性能代价。 Hashtable 的后继者 HashMap 是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的基类和一个同步的包装器 Collections.synchronizedMap ,解决了线程安全性问题。通过将基本的功能从线程安全性中分离开来, Collections.synchronizedMap 允许需要同步的用户可以拥有同步,而不需要同步的用户则不必为同步付出代价。 Hashtable 和 synchronizedMap 所采取的获得同步的简单方法 (同步 Hashtable 中或者同步的 Map 包装器对象中的每个方法) 有两个主要的不足。首先,这种方法对于可伸缩性是一种障碍,因为一次只能有一个线程可以访问hash表。同时,这样仍不足以提供真正的线程安全性,许多公用的混合操作仍然需要额外的同步。虽然诸如 get() 和 put() 之类的简单操作可以在不需要额外同步的情况下安全地完成,但还是有一些公用的操作序列,例如迭代或者put-if-absent (空则放入) ,需要外部的同步,以避免数据争用。 有条件的线程安全性 同步的集合包装器 synchronizedMap 和 synchronizedList ,有时也被称作 有条件地线程安全――所有单个的操作都是线程安全的,但是多个操作组成的操作序列却可能导致数据争用,因为在操作序列中控制流取决于前面操作的结果。 清单1中第一片段展示了公用的put-if-absent语句块――如果一个条目不在 Map 中,那么添加这个条目。不幸的是,在 containsKey() 方法返回到 put() 方法被调用这段时间内,可能会有另一个线程也插入一个带有相同键的值。如果您想确保只有一次插入,您需要用一个对 Map m 进行同步的同步块将这一对语句包装起来。 http://www-128.ibm.com/developerworks/cn/java/j-jtp07233/index.html#listing1 中其他的例子与迭代有关。在第一个例子中, List.size() 的结果在循环的执行期间可能会变得无效,因为另一个线程可以从这个列表中删除条目。如果时机不得当,在刚好进入循环的最后一次迭代之后有一个条目被另一个线程删除了,则 List.get() 将返回 null ,而 doSomething() 则很可能会抛出一个 NullPointerException 异常。那么,采取什么措施才能避免这种情况呢?如果当您正在迭代一个 List 时另一个线程也可能正在访问这个 List ,那么在进行迭代时您必须使用一个 synchronized 块将这个 List 包装起来,在 List 1 上同步,从而锁住整个 List 。这样做虽然解决了数据争用问题,但是在并发性方面付出了更多的代价,因为在迭代期间锁住整个 List 会阻塞其他线程,使它们在很长一段时间内不能访问这个列表。 ...

2012-07-08 · 2 min · 419 words · -

cxf wsdl2java

cxf wsdl2java wsdl2java -d src -client http://localhost:9000/helloWorld?wsdl 其作用上面的build.xml作用一样。 附加: wsdl2java用法: wsdl2java -p com -d src -all aa.wsdl -p 指定其wsdl的命名空间,也就是要生成代码的包名: -d 指定要产生代码所在目录 -client 生成客户端测试web service的代码 -server 生成服务器启动web service的代码 -impl 生成web service的实现代码 -ant 生成build.xml文件 -all 生成所有开始端点代码: types,service proxy,,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file. 详细用法见: http://cwiki.apache.org/CXF20DOC/wsdl-to-java.html

2012-07-06 · 1 min · 50 words · -

jvm http proxy

jvm http proxy http://i4t.org/2007/05/04/java-http-proxy-settings/ Java HTTP Proxy Settings OVERVIEW For local networks within an organization, access to the public-domain Internet is often via a HTTP Proxy. This article talks about the HTTP proxy settings for the Java environment. I did not find a good document on the Web to describe these settings; Had to discover many of them by trial-and-error. Hence this article. KEYWORDS HTTP Proxy, Java Proxy Settings, Tomcat, Application Server, Servlets, HTTP Proxy Authentication for Java, Java Application Proxy Settings ...

2012-07-05 · 2 min · 363 words · -

java 静态变量/方法

java 静态变量/方法 有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。 声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。声明为static的方法有以下几条限制: · 它们仅能调用其他的static 方法。 · 它们只能访问static数据。 · 它们不能以任何方式引用this 或super (关键字super 与继承有关,在下一章中描述) 。 如果你需要通过计算来初始化你的static变量,你可以声明一个static块,Static 块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static 初始化块: // Demonstrate static variables,methods,and blocks. class UseStatic { static int a = 3; static int b; static void meth(int x) { System.out.println(“x = " + x); System.out.println(“a = " + a); System.out.println(“b = " + b); } static { System.out.println(“Static block initialized.”); b = a * 4; } public static void main(String args[]) { meth(42); } } 一旦UseStatic 类被装载,所有的static语句被运行。首先,a被设置为3,接着static 块执行(打印一条消息),最后,b被初始化为a*4 或12。然后调用main(),main() 调用meth() ,把值42传递给x。3个println ( ) 语句引用两个static变量a和b,以及局部变量x 。 ...

2012-06-28 · 2 min · 289 words · -