Cirry's Blog

UUID类

2019-10-10
技术
java
最后更新:2024-03-22
8分钟
1568字

UUID类

根据时间戳实现一个自动的无重复的字符串定义。

  • 获取UUID:public static UUID randomUUID();
  • 根据字符串获取UUID内容:public static UUID fromString(String name);

Optional类

  • 返回空数据:public static Optional empty();
  • 获取数据:public T get();
  • 保存数据,但是不允许出现null:public static Optional of(T value);
  • 保存数据,允许为空: public static Optional ofNullable(T value);
  • 空的时候返回其他数据:public T orElse(T other);

ThreadLocal类

范例:

1
package cn.cccc.demo;
2
class 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
}
11
class 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
}
20
public 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
}

对于当前的实例,使用的是单线程模式来实现的。那么如果在多线程模式下,能不能实现同样的效果。

1
package cn.cccc.demo;
2
class 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
}
11
class 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
}
20
public 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(); 范例:解决线程同步问题
1
package cn.cccc.demo;
2
class 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
}
12
class 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
}
21
public 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); 范例:实现定时任务的处理
1
package cn.cccc.demo;
2
import java.util.Timer;
3
import java.util.TimerTask;
4
class MyTask extends TimerTask{ //任务主体
5
@Override
6
public void run() { //多线程的处理方法
7
// TODO Auto-generated method stub
8
System.out.println(Thread.currentThread().getName()+"定时任务、当前时间:"+System.currentTimeMillis());
9
}
10
}
11
public 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); 范例:实现加密与解密操作
1
package cn.cccc.demo;
2
import java.util.Base64;
3
public 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
}

公版加密意义不大,不存在安全性可言,所以还需要加盐操作。 改版:

1
package cn.cccc.demo;
2
import java.util.Base64;
3
public 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
}

尽管现在有盐值,但也不是很好。 改版:

1
package cn.cccc.demo;
2
import java.util.Base64;
3
class 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
}
33
public 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
}
本文标题:UUID类
文章作者:Cirry
发布时间:2019-10-10
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
感谢大佬送来的咖啡☕
alipayQRCode
wechatQRCode