Eclipse version:
Eclipse Java EE IDE for Web Developers.
Version: Kepler Service Release 1
Build id: 20130919-0819
lamdba学习:
public class Employ { private String name; private int salary; public Employ(String name, int salary, Department department) { super(); this.name = name; this.salary = salary; this.department = department; } private Department department; public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Employ [name=" + name + ", salary=" + salary + ", department=" + department + "]"; } }
public class Department { public Department() { super(); } public Department(String name) { super(); this.name = name; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Department [name=" + name + "]"; } }
import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.TreeSet; import java.util.stream.Collectors; public class Lambda { public static void main(String[] args) { //Collectors文档的例子 Employ e = new Employ("张三", 6000, new Department("技术部")); Employ e2 = new Employ("李四", 6500, new Department("产品部")); Employ e3 = new Employ("王五", 7500, new Department("高管")); Employ e4 = new Employ("赵六", 7500, new Department("高管")); Listpeople = Arrays.asList(e, e2, e3, e4); // Accumulate names into a List List l = new ArrayList<>(); people.stream().forEach(employ->l.add(employ.getName())); System.out.println(l); System.out.println(people.stream().map(employ->employ.getDepartment().getName()).collect(Collectors.toList())); System.out.println(people.stream().map(employ->employ.getName()).collect(Collectors.toList())); System.out.println(people.stream().map(Employ::getName).collect(Collectors.toList())); // Accumulate names into a TreeSet System.out.println(people.stream().map(Employ::getName).collect(Collectors.toCollection(HashSet::new))); System.out.println(people.stream().map(Employ::getName).collect(Collectors.toCollection(TreeSet::new))); // Convert elements to strings and concatenate them, separated by commas System.out.println(people.stream().map(Employ::toString).collect(Collectors.joining(", "))); // Compute sum of salaries of employee System.out.println(people.stream().collect(Collectors.summingInt(Employ::getSalary))); // Group employees by department Map > byDept = people.stream().collect(Collectors.groupingBy(Employ::getDepartment)); System.out.println(byDept); // Compute sum of salaries by department Map totalByDept = people.stream().collect(Collectors.groupingBy(Employ::getDepartment, Collectors.summingInt(Employ::getSalary))); System.out.println(totalByDept); // Partition students into passing and failing Map > passingFailing = people.stream().collect(Collectors.partitioningBy(ele->ele.getSalary()>6000)); System.out.println(passingFailing); } }
反射获取目标class的目标属性泛型实际类型
(参考资料:Java反射与动态代理):
package com.tch.test.testextend; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class GetGenericActualTypeTest { public static void main(String[] args) { getGenericActualType(User.class, "username"); getGenericActualType(User.class, "friends"); getGenericActualType(User.class, "friendUsername"); getGenericActualType(User.class, "friendNameMap"); } public static void getGenericActualType(Class> clazz, String fieldName){ System.out.println("begin to getGenericActualType for field: " + fieldName); Field field = null; try { field = clazz.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } if(field != null){ /** * 如果field是一个普通的属性,不带有泛型,则getGenericType() 和 getType()的结果一样,都是该field的类型 * 如果field是一个带有泛型的属性,则getGenericType()得到的是泛型类型,需要类型转换为ParameterizedType, 和getType()的结果就不一样了 */ // 拿到属性的泛型类型(比如Listlist, 得到的就是String) Type genericType = field.getGenericType(); // getType() 得到的是属性的类型 Type type = field.getType(); System.out.println("fieldName: " + fieldName + ", genericType equals type? " + genericType.toString().equals(type.toString())); if(genericType instanceof ParameterizedType){ // 获取泛型的实际类型 Type[] actualTypes = ((ParameterizedType) genericType).getActualTypeArguments(); if(actualTypes.length > 0){ for(Type actualType : actualTypes){ // 类型转为Class Class> actualClass = (Class>) actualType; System.out.println(actualClass); } } } } System.out.println(); System.out.println(); } class User{ private int age; private String username; private List friends; private List friendUsername; private Map friendNameMap; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public List getFriends() { return friends; } public void setFriends(List friends) { this.friends = friends; } public List getFriendUsername() { return friendUsername; } public void setFriendUsername(List friendUsername) { this.friendUsername = friendUsername; } public Map getFriendNameMap() { return friendNameMap; } public void setFriendNameMap(Map friendNameMap) { this.friendNameMap = friendNameMap; } } }
import java.util.List; public class Class1 { private Listlist; private String name1; private void add(){ System.out.println("add---"); } }
反射工具类:
package utils.common; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import model.Company; import model.common.User; public final class ReflectionUtils { public static void main(String[] args) { Listlist = new ArrayList<>(); CustomerRequestParam param = new CustomerRequestParam(); param.setPage(1); param.setPageSize(1); param.setUserType(1); list.add(param); param = new CustomerRequestParam(); param.setPage(2); param.setPageSize(2); param.setUserType(2); list.add(param); param = new CustomerRequestParam(); param.setPage(3); param.setPageSize(3); param.setUserType(3); list.add(param); System.out.println(getAllFields(list, "page")); System.out.println(getAllFields(list, "pageSize")); System.out.println(getAllFields(list, "userType")); CustomerRequest request = new CustomerRequest(); User user = new User(); Company company = new Company(); user.setCompany(company); request.setUser(user); List requests = new ArrayList<>(); requests.add(request); System.out.println(getAllFields(requests, "user.company")); } public static List getAllFieldList(Collection> collection, String fieldName){ List list = new ArrayList<>(getAllFields(collection, fieldName)); return list; } public static Set getAllFieldSet(Collection> collection, String fieldName){ Set result = getAllFields(collection, fieldName); return result; } /** * 获取collection中每个元素的属性值的集合 * @param collection * @param fieldName * @return */ @SuppressWarnings("unchecked") public static Set getAllFields(Collection> collection, String fieldName){ if(collection == null || collection.isEmpty()){ return Collections.EMPTY_SET; } if (fieldName == null || fieldName.trim().isEmpty()) { throw new IllegalArgumentException("param fieldName is empty"); } Class> clazz = getElementsClass(collection); Method[] methods = getAllGetterMethods(clazz, fieldName); if(methods == null || methods.length == 0){ throw new RuntimeException("no getter method for field " + fieldName); } Set result = new HashSet<>(); for(Object ele : collection){ Object object = ele; int methodLength = methods.length; for(int i=0; i clazz, String fieldName){ List allGetterMethods = new ArrayList<>(); int dotIndex = fieldName.indexOf("."); if(dotIndex == -1){ //说明没有".", 不需要递归 allGetterMethods.add(getterMethod(clazz, fieldName)); }else{ String[] fieldNames = fieldName.split("\\."); Class> returnClass = clazz; for(int i=0; i clazz, String fieldName) { Method gettMethod = null; String getterMethodName = getterMethodName(fieldName); try { gettMethod = clazz.getDeclaredMethod(getterMethodName); if(gettMethod != null){ return gettMethod; } } catch (Exception e) { } try { gettMethod = clazz.getMethod(getterMethodName); if(gettMethod != null){ return gettMethod; } } catch (Exception e) { } return null; } /** * 获取给定属性的get方法名 * @param fieldName * @return */ private static String getterMethodName(String fieldName) { return "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); } /** * 获取容器中元素的class * @param collection * @return */ private static Class> getElementsClass(Collection> collection) { return collection.iterator().next().getClass(); } }
package com.tch.test.concurrent; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class ReturnTest { private int i; public static void main(String[] args) throws Exception{ m1("name1", Class1.class); } /** * Created on: 2013-11-27 *Discription: 反射获取目标class的目标属性泛型实际类型
* @param fieldName 属性名 * @param clazz 目标Class对象 * @return void */ public staticvoid m1(String fieldName,Class clazz){ try { Field field = clazz.getDeclaredField(fieldName); Type type = field.getGenericType(); if (type instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) type; Type[] actualTypes = paramType.getActualTypeArguments(); for (Type aType : actualTypes) { if (aType instanceof Class>) { Class> clz = (Class>) aType; System.out.println(clz.getName()); } } } }catch (Exception e) { e.printStackTrace(); } } }
访问私有方法:
public static void callHiddenMethod(Object a, String methodName) throws Exception { Method g = a.getClass().getDeclaredMethod(methodName); g.setAccessible(true); g.invoke(a); }
获取目标Class对象的实际父类泛型类型:
public class Father{ }
public class Child extends Father{ }
import java.lang.reflect.ParameterizedType; public class GenericUtils { /** * Created on: 2013-11-27 *Discription: 获取目标Class对象的实际父类泛型类型
* @param clazz 目标Class对象 * @return Class*/ @SuppressWarnings("unchecked") public static Class getGenericType(Class clazz){ return (Class )((ParameterizedType)clazz.getGenericSuperclass()).getActualTypeArguments()[0]; } }
测试方法:
public static void main(String[] args) throws Exception { System.out.println(GenericUtils.getGenericType(Child.class)); }
快速排序 / 冒泡排序:
package com.tch.test; public class QuickSort { public void quickSort(int[] arr, int from, int to) { if(from >= to){ return; } int left = from; int right = to; int tmp = arr[from]; while(left < right){ while(right > left){ if(arr[right] < tmp){ arr[left] = arr[right]; break; } right --; } while(left < right){ if(arr[left] > tmp){ arr[right] = arr[left]; break; } left++; } } arr[left] = tmp; quickSort(arr, from, left-1); quickSort(arr, right+1, to); } public void maopao(int[] arr){ int length = arr.length; int tmp = 0; for(int i=0;iarr[j]){ tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } } public static void main(String[] args) { int[] arr = new int[] { 1,4,8,2,5,9,7,6,3,10 ,3,5,8,0,1,6 }; QuickSort sort = new QuickSort(); //sort.quickSort(strVoid, 0, arr.length - 1); sort.maopao(arr); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } } }
读取一行:
/** * Created on 2013-5-22 *Discription:读取一行内容
* @param in 输入流 * @return String 读取到的一行内容 */ public static String readLine(InputStream in){ String result = null; try { byte[] b = new byte[1]; int n = -1; while((n = in.read()) != -1){ if(n == '\r' || n == '\n'){ break; }else{ b[b.length-1] = (byte)n; b = Arrays.copyOf(b, b.length+1); } } if(b.length <= 1){ return null; } b = Arrays.copyOf(b, b.length-1); return new String(b,"utf-8"); } catch (IOException e) { e.printStackTrace(); } return result; }
servlet下载pdf:
package com.tch.excel; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ExportExcel extends HttpServlet { /** * The doGet method of the servlet.
* * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * The doPost method of the servlet.
* * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/pdf"); File file = new File("E:\\中文.pdf"); response.addHeader("Content-Disposition", "attachment;"+new String(("filename=我的Excel.pdf").getBytes("GBK"), "ISO-8859-1")); response.setContentLength((int) file.length()); PrintWriter out = response.getWriter(); FileReader in = new FileReader(file); char[] b = new char[10240]; int n = -1; while((n=in.read(b)) != -1){ out.write(b, 0, n); } out.flush(); out.close(); } }
下载excel::(只需要改contentType和文件后缀即可)
package com.tch.excel; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class ExportExcel extends HttpServlet { /** * The doGet method of the servlet.
* * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * The doPost method of the servlet.
* * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/x-xls;charset=utf-8"); response.addHeader("Content-Disposition", "attachment;"+new String(("filename=我的Excel.xls").getBytes("GBK"), "ISO-8859-1")); PrintWriter out = response.getWriter(); out.print(" 中文内容"); out.flush(); out.close(); } }
下载word:(只需要改contentType和文件后缀即可)
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/msword;charset=utf-8"); response.addHeader("Content-Disposition", "attachment;"+new String(("filename=我的Excel.doc").getBytes("GBK"), "ISO-8859-1")); PrintWriter out = response.getWriter(); out.print(" 中文内容"); out.flush(); out.close(); }
导出excel:
static void export() throws Exception{ HSSFWorkbook wb = new HSSFWorkbook(); Sheet sheet = wb.createSheet("007"); HSSFCellStyle style = wb.createCellStyle(); //背景颜色(注意不是setFillBackgroundColor) style.setFillForegroundColor(HSSFColor.WHITE.index); //背景颜色填充样式 style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //上下左右边框样式 style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); //上下左右边框颜色 style.setRightBorderColor(HSSFColor.GREY_25_PERCENT.index); style.setBottomBorderColor(HSSFColor.GREY_25_PERCENT.index); style.setLeftBorderColor(HSSFColor.GREY_25_PERCENT.index); style.setTopBorderColor(HSSFColor.GREY_25_PERCENT.index); //水平、垂直对齐方式 style.setAlignment(HSSFCellStyle.ALIGN_LEFT); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); Row row = sheet.createRow((short) 1); Cell cell = row.createCell((short) 1); cell.setCellValue("X"); cell.setCellStyle(style); cell = row.createCell((short) 2); cell.setCellValue("X"); cell.setCellStyle(style); FileOutputStream fileOut = new FileOutputStream("f:workbook.xls"); wb.write(fileOut); fileOut.close(); }
产生验证码(以servlet为例):
package com.tch.excel; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AuthImage extends HttpServlet { private static final long serialVersionUID = 1L; private static char[] codeArr = new char[] {'a','b','c','d','e','f','g','h','i', 'j','k','l','m','n','o','p','q','r', 's','t','u','v','w','x','y','z','A', 'B','C','D','E','F','G','H','I','J', 'K','L','M','N','O','P','Q','R','S', 'T','U','V','W','X','Y','Z','0','1', '2','3','4','5','6','7','8','9'}; private Random random = new Random(); public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int length = codeArr.length; int width = 200; int height = 100; //存放生成的字符 String code = ""; //存放最终的字符组成的字符串验证码 String validateCode = ""; //构建BufferedImage对象,用来存储生成的验证码图片(临时存放在内存中) BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //获取BufferedImage的Graphics对象,Graphics起着画笔的作用,用来写验证码及其它内容 Graphics graphics = bufferedImage.getGraphics(); //开始在BufferedImage对象上面涂背景色 graphics.setColor(Color.white); graphics.fillRect(0, 0, width-1, height-1); //在BufferedImage对象上面画边框 graphics.setColor(Color.black); graphics.drawRect(0, 0, width-1, height-1); //设置要画的字符串的字体 graphics.setFont(new Font("Comic Sans MS",Font.PLAIN,70)); for(int i=0;i<4;i++){ //随机产生字符 code=""+codeArr[random.nextInt(length)]; //随机产生颜色 graphics.setColor(getRandColor()); //将字符写到BufferedImage对象上(Graphics最终是写到对应的BufferedImage对象上面) graphics.drawString(code, 5+i*50, 70); //添加到验证码字符串里面 validateCode += code; } System.out.println("validateCode : "+validateCode); //释放画笔占用的资源 graphics.dispose(); //将生成的图片通过response的输出流返回给页面 ImageIO.write(bufferedImage, "JPEG", response.getOutputStream()); } //产生随机颜色 private Color getRandColor() { Random random = new Random(); Color color[] = new Color[10]; color[0] = new Color(32, 158, 25); color[1] = new Color(218, 42, 19); color[2] = new Color(31, 75, 208); return new Color(random.nextInt(220), random.nextInt(220), random.nextInt(220)); } }
然后在web.xml中配置该servlet,页面如下(xxx为项目名,servlet/authImage为servlet的映射路径):
导出表格到PDF实例
任务调度ScheduledExecutorService:
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; public class ScheduledTask { private static SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss"); UncaughtExceptionHandler exceptionHandler = null; private void task1() { exceptionHandler = new UncaughtExceptionHandler(){ @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("thread: "+t+" , throwable : "+e); } }; ScheduledExecutorService executor = Executors.newScheduledThreadPool(2, new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler(exceptionHandler);//异常处理 return thread; } }); //上次任务和下次任务的开始时间间隔为固定值(这里是6 s),不论任务本身执行多长时间,但是任务时间如果超过时间间隔,就会推迟下次任务的启动时间 executor.scheduleAtFixedRate(new Task("AtFixedRate"), 0, 6, TimeUnit.SECONDS); //从上次任务结束到下次任务的开始时间间隔为固定值(这里是6 s),和任务本身的执行时间有关系 executor.scheduleWithFixedDelay(new Task("WithFixedDelay"), 0, 6, TimeUnit.SECONDS); } public class Task implements Runnable { private String name; public Task(String name){ this.name = name; } public void run(){ System.out.println("线程 : "+name+" 启动"+format.format(new Date())); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程 : "+name+"结束"+format.format(new Date())); } } public static void main(String[] args) { new ScheduledTask().task1(); } }
2种方式实现生产着消费者:
一:使用比较低级的方式:
import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Test2 { public static void main(String[] args) throws InterruptedException { Test2 t = new Test2(); Queuecontainer = new LinkedList (); ExecutorService e = Executors.newFixedThreadPool(3); e.execute(t.new Producer(container)); e.execute(t.new Consumer(container)); e.shutdown(); } class Producer implements Runnable{ Queue container; public Producer(Queue container){ this.container = container; } int i=0; Integer get(){ i++; return i; } @Override public void run() { try { while(true){ synchronized(container){ while(container.size()>3){ container.wait(); } Integer j = get(); container.add(j); System.out.println("生产了:"+j); container.notifyAll(); Thread.sleep(500); } } } catch (InterruptedException e) { e.printStackTrace(); } } } class Consumer implements Runnable{ Queue container; public Consumer(Queue container){ this.container = container; } @Override public void run() { try { while(true){ synchronized(container){ while(container.isEmpty()){ container.wait(); } Integer butter =container.poll(); System.err.println("消费了: "+butter); container.notifyAll(); Thread.sleep(500); } } } catch (InterruptedException e) { e.printStackTrace(); } } } }
二:使用高级点,省事的方式:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; public class Test { public static void main(String[] args) { Test t = new Test(); LinkedBlockingQueuecontainer = new LinkedBlockingQueue (); ExecutorService e = Executors.newFixedThreadPool(3); e.execute(t.new Producer(container)); e.execute(t.new Consumer(container)); e.shutdown(); } class Producer implements Runnable{ LinkedBlockingQueue container; public Producer(LinkedBlockingQueue container){ this.container = container; } int i=0; Integer get(){ i++; return i; } @Override public void run() { try { while(true){ Integer j = get(); System.out.println("生产了:"+j); container.put(j);//LinkedBlockingQueue会自动处理容器为空或者过大的情况(会等待) Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } class Consumer implements Runnable{ LinkedBlockingQueue container; public Consumer(LinkedBlockingQueue container){ this.container = container; } @Override public void run() { try { while(true){ Integer butter =container.take();//LinkedBlockingQueue会自动处理容器为空或者过大的情况(会等待) System.err.println("消费了: "+butter); Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } }
标准jdbc连接步骤(使用了批处理,以及异常回滚):
void jdbc() throws Exception{ Connection conn = null; PreparedStatement statement = null; try { Class.forName("com.mysql.jdbc.Driver");//加载数据库驱动类 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");//获取连接 statement = conn.prepareStatement("insert into coures(id,name,age) values(?,?,?)");//创建PreparedStatement conn.setSavepoint();//设置保存点 conn.setAutoCommit(false);//关闭事务自动提交 for(int i=0;i<100;i++){ statement.setInt(1, i);//索引从 1 开始 statement.setString(2, "tch"); statement.setInt(3, 23); statement.addBatch();//添加到批处理 } statement.executeBatch();//执行批处理 conn.commit();//没有异常,提交事务 } catch (Exception e) { if(conn != null){ conn.rollback();//出现异常时,回滚到保存点 } e.printStackTrace(); }finally{//关闭资源 if(statement != null){ statement.close(); } if(conn != null){ conn.close(); } } }
最简单的死锁:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Test { Object o1 = new Object(),o2 = new Object(),o = new Object(); public static void main(String[] args) throws Exception { final Test t = new Test(); ExecutorService e = Executors.newFixedThreadPool(2); e.execute(new Runnable() { @Override public void run() { try { t.syn1(); } catch (Exception e) { e.printStackTrace(); } } }); e.execute(new Runnable() { @Override public void run() { try { t.syn2(); } catch (Exception e) { e.printStackTrace(); } } }); e.shutdown(); } void syn1() throws Exception{ synchronized(o1){ System.out.println("syn1 获得 o1 的锁"); Thread.sleep(50);//让出CPU,让syn2有机会获得o2的锁 synchronized(o2){ System.out.println("syn1 获得 o2 的锁"); } } } void syn2() throws Exception{ synchronized(o2){ System.out.println("syn2 获得 o2 的锁"); Thread.sleep(50);//让出CPU,让syn1有机会获得o1的锁 synchronized(o1){ System.out.println("syn2 获得 o1 的锁"); } } } }
log4j配置:
log4j.properties
log4j.rootLogger=debug,stdout,DAILY_ROLLING_FILE log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n ######################## # DailyRolling File ######################## log4j.appender.DAILY_ROLLING_FILE=org.apache.log4j.DailyRollingFileAppender log4j.appender.DAILY_ROLLING_FILE.Append=true log4j.appender.DAILY_ROLLING_FILE.Threshold=debug log4j.appender.DAILY_ROLLING_FILE.Encoding=UTF-8 #通过读取系统变量来制定日志目标位置 log4j.appender.DAILY_ROLLING_FILE.File=${logDir}/log.txt log4j.appender.DAILY_ROLLING_FILE.DatePattern='.'yyyy-MM-dd log4j.appender.DAILY_ROLLING_FILE.layout=org.apache.log4j.PatternLayout log4j.appender.DAILY_ROLLING_FILE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%c] %m%n ################### # Console Appender ################### log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.Threshold=debug log4j.appender.CONSOLE.Target=System.out log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p (%c:%L) - %m%n ################### #指定特定类的输出级别 ################### #指定struts2日志级别 log4j.logger.com.opensymphony.xwork2=info log4j.logger.org.apache.struts2=info #指定某个类的日志级别 log4j.logger.com.test.LogTest=info
getResourceAsStream、getResource用法:
public class ResourceTest { public static void main(String[] args) { //Class.getResource("path") //path不以/开头,表示和当前文件同目录 System.out.println(ResourceTest.class.getResource("").getPath()); //path以/开头,表示classpath路径 System.out.println(ResourceTest.class.getResource("/").getPath()); //ClassLoader.getResource("path") //path不需要以/开头,表示classpath路径 System.out.println(ResourceTest.class.getClassLoader().getResource("").getPath()); //这种方式也可以获取classpath路径 System.out.println(ResourceTest.class.getProtectionDomain().getCodeSource().getLocation().getPath()); } }
注解的用法和处理(自定义注解、使用注解、处理注解)
web.xml加载顺序:
context-param -> listener -> filter -> servlet
web.xml中的listener的加载顺序由该listener在web.xml中的配置顺序决定,filter的顺序由web.xml中的filter-mapping顺序决定,servlet的顺序由web.xml中的servlet-mapping顺序决定
com.tch.Listener2 com.tch.Listener1
可以看出先执行2,2等待3 s之后执行1,1在等待3 s,完全是线性执行的。
Listerner1:
package com.tch; import java.util.concurrent.TimeUnit; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class Listener1 implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { System.out.println("1 destroy"); } @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("1 init"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1 sleep complete"); } }