JAVA笔记
来源:互联网 发布:java导出csv文件乱码 编辑:程序博客网 时间:2024/06/04 18:31
String
==与equals
看了一部分讲解,个人理解,应该时刻记得String是一个类,并不是int等基本类型。由于类是用new在堆上创建对象,且对象的地址存在于栈中,而int等基本类型是在栈上创建。所以用“==”比较的是栈内的值,也就是说用“==”比较基本类型时,比较的是基本类型的取值,而用“==”比较类的对象时,比较的是该对象的地址。当使用“equals”比较时,比较的是堆中的取值是否相同。因此String等类在比较对象的取值时应该用equals。
实时读写文件
写properties
不使用Spring 的 Environment
有一次在编码的时候,使用的是Spring 的Environment类,导致无法实时读取,可能是由于Environment类只是在程序启动的时候将文件读入内存,之后不再反复读取的原因。只要正常使用Properties类,在每次读取时重新打开输入流,读取之后关闭输入流即可做到实时读取。
SafeProperties properties = new SafeProperties(); try { InputStream inputStream = new BufferedInputStream(new FileInputStream(propertiesFilePath)); properties.load(inputStream); inputStream.close(); } catch (Exception exception) { exception.printStackTrace(); }
只读写内存中的,不写入实体文件
参考http://bbs.csdn.net/topics/392066071,使用如下方式:
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("BaseConfig.properties"); OutputStream outputStream = new FileOutputStream(new File(this.getClass().getClassLoader().getResource("BaseConfig.properties").getFile()));
此时加载的是class编译后的执行路径,可以做到写完数据后,下次读的时候读取到的是新数据。但从始至终,即使程序退出,也不会将数据写入到实际的文件中。例子:
public class ConfigUtil { private static ConfigUtil instance; private static Properties properties = null; private ConfigUtil() { properties = new Properties(); InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("BaseConfig.properties"); try { properties.load(inputStream); } catch (IOException ex) { Logger.getLogger(ConfigUtil.class.getName()).log(Level.SEVERE, null, ex); }finally{ if (inputStream!=null) { try { inputStream.close(); } catch (IOException ex) { Logger.getLogger(ConfigUtil.class.getName()).log(Level.SEVERE, null, ex); } } } } public static ConfigUtil getInstance() { if (instance == null) { instance = new ConfigUtil(); } return instance; } public String getValueByKey(String key) { return (String) properties.get(key) == null ? "空" : (String) properties.get(key); } public void setValueByKey(String key ,String value) throws FileNotFoundException, IOException { properties.setProperty(key, value); OutputStream outputStream = new FileOutputStream(new File(this.getClass().getClassLoader().getResource("BaseConfig.properties").getFile())); properties.store(outputStream, ""); outputStream.close(); } public static void main(String[] a) throws FileNotFoundException, IOException { ConfigUtil configTool = ConfigUtil.getInstance(); System.out.println(configTool.getValueByKey("test")); configTool.setValueByKey("test", "33"); System.out.println(configTool.getValueByKey("test")); configTool.setValueByKey("test", "44"); System.out.println(configTool.getValueByKey("test")); configTool.setValueByKey("test", "55"); System.out.println(configTool.getValueByKey("test")); }}
使用线程读入,该方法没有做到实时
使用新的线程读入properties文件,参考http://java-my-life.iteye.com/blog/1313706
InputStream in = new BufferedInputStream(new FileInputStream(Thread .currentThread().getContextClassLoader().getResource( "test.properties").getPath()));
例子
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; public class Test extends Thread{ public void run() { while(true){ try { this.sleep(1000); readProperties(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private static void readProperties() { Properties p = new Properties(); try { InputStream in = new BufferedInputStream(new FileInputStream(Thread .currentThread().getContextClassLoader().getResource( "test.properties").getPath())); p.load(in); in.close(); String name = p.getProperty("name"); String id = p.getProperty("id"); System.out.println("id=" + id + "\t name=" + name); } catch (Exception e1) { e1.printStackTrace(); } } public static void main(String[]args) { new Test().start(); } }
读properties
防止乱码
为了防止乱码,load时可以使用InputStreamReader,然后设置charsetName为utf-8。但是使用这种方式写入时,无论是否使用SafeProperties等自定义的类,都无法保留properties文件中的注释及空行。所以尽量读写分离。
Properties properties = new SafeProperties(); InputStream inputStream = new BufferedInputStream(new FileInputStream(propertiesFilePath)); properties.load(new InputStreamReader(inputStream, "utf-8")); inputStream.close();
读取JAR包内的文件
获取流
被读取的文档路径要设置成以JAR包根目录为基础的路径,如下图,environment.properties文件在JAR包根目录下的properties文件夹内,因此路径要写成”properties/environment.properties”
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("properties/environment.properties"); properties.load(inputStream); inputStream.close();
同步/互斥
Semaphore
模拟mutex
在定义Semaphore的时候,令可用资源数量=1,即可模拟mutex。
定时任务
ScheduledExecutorService
启动
使用ScheduledExecutorService的好处有很多,参考说明,相比于Timer具体有三处优势,1是支持多线程多任务,2是对于每个线程异常的单独处理,3是Timer执行周期任务时依赖系统时间,当系统时间变化时,会影响执行上的变化,ScheduledExecutorService基于时间的延迟,不会由于系统时间的改变发生执行变化。使用方法参考例子:
package com.effective.common.concurrent.execute;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class Schedule { private static DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); private static DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd"); private static ScheduledExecutorService excutor = Executors.newSingleThreadScheduledExecutor(); /** * 按指定频率周期执行某个任务 <br> * 初始化延迟0ms开始执行,每隔5ms重新执行一次任务。 */ public void fixedRate(){ excutor.scheduleAtFixedRate(new EchoServer(), //执行线程 0, //初始化延迟 5000, //两次开始的执行的最小时间间隔 TimeUnit.MILLISECONDS //计时单位 ); } /** * */ public void fixDelay(){ excutor.scheduleWithFixedDelay(new EchoServer(),//执行线程 0, //初始化延迟 5000, //前一次执行结束到下一次执行开始的间隔时间 TimeUnit.MILLISECONDS); } /** * 每天晚上8点执行一次 */ public void dayOfDelay(String time){ ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); long oneDay = 24 * 60 * 60 * 1000; long initDelay = getTimeMillis("20:00:00") - System.currentTimeMillis(); initDelay = initDelay > 0 ? initDelay : oneDay + initDelay; executor.scheduleAtFixedRate( new EchoServer(), initDelay, oneDay, TimeUnit.MILLISECONDS); } /** * 获取给定时间对应的毫秒数 * @param string "HH:mm:ss" * @return */ private static long getTimeMillis(String time) { try { Date currentDate = dateFormat.parse(dayFormat.format(new Date()) + " " +time); return currentDate.getTime() ; } catch (ParseException e) { e.printStackTrace(); } return 0; } public static void main(String[] args){ Schedule schedule = new Schedule(); schedule.fixedRate(); schedule.fixDelay(); }}
取消定时任务
使用下述语句可以取消已经建立的定时任务,但是我仅仅在线程未执行或执行结束的时候用过,执行shutdown后该线程不再定时启动。若该任务线程正在执行,不知道是否可以强行终止。
scheduledExecutorService.shutdown();
当使用newSingleThreadScheduledExecutor()创建时,可能是由于创建的是单独的一个线程,所以在线程创建之后,线程池中已经空了。在shutdown之后,当再次启动定时任务时,会由于线程池空了而报错,异常信息:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@6386eba1 rejected from java.util.concurrent.ScheduledThreadPoolExecutor@5e5a567f[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
因此在使用newSingleThreadScheduledExecutor()且执行了shutdown操作后,若是想再次启动定时任务,需要重新通过newSingleThreadScheduledExecutor()获取对象。
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
Swing
多线程中不显示界面
下图为一个创建界面的类,当在绘制swing界面的类内部,直接在函数中使用sleep或semaphore的acquire函数时,会导致界面显示异常,仅仅剩下一个frame,无法显示加载的pannel。
因此若需要在多个线程所控制的界面之间切换,要在线程内的run函数中写sleep,acquire等函数,这样才能正常显示。至于导致这一问题的原因,还不清楚,需要再查资料看一看,怀疑是因为sleep等导致阻塞,使得pannel无法显示。
设置图标
设置程序显示图标
为JFrame添加图标,由于java只识别jpg、png等,不能识别ico,因此不能使用ico图片。
Image image = Toolkit.getDefaultToolkit().getImage(iconPath + "\\mainForm.png"); frame.setIconImage(image);
窗口按钮
不关闭窗口
当点击窗口右上角的红叉时,不关闭窗口,并执行重写的windowClosing操作。
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { JOptionPane.showMessageDialog(null, "请等待数据处理结束!"); } });
- java笔记
- JAVA笔记
- java笔记
- java笔记
- JAVA笔记
- java笔记
- Java 笔记
- java笔记
- java 笔记
- java笔记
- java笔记
- java笔记
- Java笔记
- java笔记
- java笔记
- Java笔记
- java笔记
- java笔记
- VMware 家族系列各组件介绍
- java中加号为连接字符与运算符的区别
- 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟
- 模板实现顺序表、双链表
- 【Java】常用控件和事件处理
- JAVA笔记
- HDU 1016 Prime Ring Problem【深搜练习】
- 希尔排序与堆排序
- Java任务调度框架Quartz教程实例
- 模板的分离编译
- hibernate框架双向一对多例子(十一)
- Centos中安装配置local/standalone模式和伪分布式模式hadoop集群
- 动态规划之数字三角形
- 图像处理(七):图像变换