UUID类
根据时间戳实现一个自动的无重复的字符串定义。
- 获取UUID:public static UUID randomUUID();
- 根据字符串获取UUID内容:public static UUID fromString(String name);
Optional类
- 返回空数据:public static
Optional empty(); - 获取数据:public T get();
- 保存数据,但是不允许出现null static
Optional of(T value); - 保存数据,允许为空: public static
Optional ofNullable(T value); - 空的时候返回其他数据:public T orElse(T other);
ThreadLocal类
范例:
package cn.cccc.demo;class Channel{ //消息发送通道 private static Message message; public static void setMessage(Message m){ message = m; } public static void send(){ //发送消息 System.out.println("[发送消息]"+message.getInfo()); }}class Message { //要发送的消息体 private String info; public void setInfo(String info){ this.info = info; }12 collapsed lines
public String getInfo(){ return info; }}public class Demo { public static void main(String[] args) { Message msg = new Message(); //实例化消息主体 msg.setInfo("www.ccc.com"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 }}对于当前的实例,使用的是单线程模式来实现的。那么如果在多线程模式下,能不能实现同样的效果。
package cn.cccc.demo;class Channel{ //消息发送通道 private static Message message; public static void setMessage(Message m){ message = m; } public static void send(){ //发送消息 System.out.println("["+Thread.currentThread().getName()+"发送消息]"+message.getInfo()); }}class Message { //要发送的消息体 private String info; public void setInfo(String info){ this.info = info; }30 collapsed lines
public String getInfo(){ return info; }}public class Demo { public static void main(String[] args) { new Thread(()->{ Message msg = new Message(); //实例化消息主体 msg.setInfo("第一个线程消息"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 },"发送者A").start(); new Thread(()->{ Message msg = new Message(); //实例化消息主体 msg.setInfo("第二个线程消息"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 },"发送者B").start(); new Thread(()->{ Message msg = new Message(); //实例化消息主体 msg.setInfo("第三个线程消息"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 },"发送者C").start(); }}//运行结果://[发送者C发送消息]第一个线程消息//[发送者A发送消息]第一个线程消息//[发送者B发送消息]第一个线程消息这个时候消息处理产生了影响,在设置消息的时候,可能第一个人的消息还没发出去,就已经被第二个人给修改了message内容。导致数据覆盖不同步。 在保持Channel(所有消息发送的通道)核心结构不改变的情况下,需要考虑到每个人线程独立操作问题。发现对于Channel类而言除了要保留有发送的消息之外,还应该多存放有一个每一个线程的的标记(当前线程)那么这时候就可以用ThreadLocal类来保存数据。在ThreadLocal类里面提供有如下的操作方法:
- 构造方法:public ThreadLocal();
- 设置数据::public void set(T value);
- 取出数据:public T get();
- 删除数据 :public void remove(); 范例:解决线程同步问题
package cn.cccc.demo;class Channel{ //消息发送通道 private static final ThreadLocal<Message> THREADLOCAL = new ThreadLocal<Message>(); private Channel(){} //私有实例化 public static void setMessage(Message m){ THREADLOCAL.set(m);//向ThreadLocal中保存数据 } public static void send(){ //发送消息 System.out.println("["+Thread.currentThread().getName()+"发送消息]"+THREADLOCAL.get().getInfo()); }}class Message { //要发送的消息体 private String info; public void setInfo(String info){ this.info = info;31 collapsed lines
} public String getInfo(){ return info; }}public class Demo { public static void main(String[] args) { new Thread(()->{ Message msg = new Message(); //实例化消息主体 msg.setInfo("第一个线程消息"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 },"发送者A").start(); new Thread(()->{ Message msg = new Message(); //实例化消息主体 msg.setInfo("第二个线程消息"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 },"发送者B").start(); new Thread(()->{ Message msg = new Message(); //实例化消息主体 msg.setInfo("第三个线程消息"); //设置要发送的内容 Channel.setMessage(msg); //设置发送的消息 Channel.send(); //发送消息 },"发送者C").start(); }}//运行结果://[发送者C发送消息]第三个线程消息//[发送者A发送消息]第一个线程消息//[发送者B发送消息]第二个线程消息定时调度
- java.util.TimerTask类:实现定时任务处理
- java.util.Timer类:进行任务的启动,启动的方法;
- 任务启动:public void schedule(TimerTask task, long delay);
- 间隔触发:public void schedule(TimerTask task, long delay, long period); 范例:实现定时任务的处理
package cn.cccc.demo;import java.util.Timer;import java.util.TimerTask;class MyTask extends TimerTask{ //任务主体 @Override public void run() { //多线程的处理方法 // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName()+"定时任务、当前时间:"+System.currentTimeMillis()); }}public class Demo { public static void main(String[] args) { Timer timer = new Timer(); //定时任务 timer.schedule(new MyTask(), 1000, 1000); }1 collapsed line
}base64的加密与解密 Base64有两个内部类:
- Base64.Encoder:进行加密处理
- 加密处理:public byte[] encode(byte[] src);
- Base64.Decoder:进行解密处理
- 解密处理:public byte[] decode(byte[] src); 范例:实现加密与解密操作
package cn.cccc.demo;import java.util.Base64;public class Demo { public static void main(String[] args) { String msg = "www.ccc.com"; //要发送的信息 String encMsg =new String(Base64.getEncoder().encode(msg.getBytes())); System.out.println(encMsg); String oldMsg =new String( Base64.getDecoder().decode(encMsg)); System.out.println(oldMsg); }}公版加密意义不大,不存在安全性可言,所以还需要加盐操作。 改版:
package cn.cccc.demo;import java.util.Base64;public class Demo { public static void main(String[] args) { String salt = "带上我就是加盐操作了"; String msg = "www.ccc.com" + "{" + salt + "}"; //要发送的信息 String encMsg =new String(Base64.getEncoder().encode(msg.getBytes())); System.out.println(encMsg); String oldMsg =new String( Base64.getDecoder().decode(encMsg)); System.out.println(oldMsg); }}尽管现在有盐值,但也不是很好。 改版:
package cn.cccc.demo;import java.util.Base64;class StringUtil{ private static final String SALT = "www.cirry,cn"; //公共的盐值 private static final int REPEAT = 5; //加密次数 /** * 加密处理 * @param str 要加密的字符串,需要与盐值整合 * @return 加密后的数据 */ public static String encode(String str){ //加密处理 String temp = str + "{"+ SALT+ "}"; byte data [] = temp.getBytes(); //将字符串变为字节数组 for(int x = 0; x < REPEAT ; x ++) { data = Base64.getEncoder().encode(data);//重复加密24 collapsed lines
} return new String(data); }
/** * 进行解密处理 * @param str 要解密的字符串 * @return 解密的原始数据 */ public static String decode(String str){ byte data [] = str.getBytes(); for(int x = 0 ; x < REPEAT; x++){ data = Base64.getDecoder().decode(data); } return new String(data).replaceAll("\\{\\w+\\}", ""); }}public class Demo { public static void main(String[] args) { String str = StringUtil.encode("cirry"); System.out.println(str); System.out.println(StringUtil.decode(str)); }}