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