Java开发支持类库-阿里云Java高级编程学习笔记

UUID

  • 一般在获取UUID的时候往往都是随机生成,通过以下方式获取:

    // 获取UUID对象
    public static UUID randomUUID();
    
    // 根据字符串获取UUID内容
    public static UUID fromString(String name);
    
  • 在对一些文件进行自动命名处理的情况下,UUID非常好用

Optional

  • Optional类的功能是进行null的相关处理

  • 该类提供如下的操作方法:

    // 返回空数据
    public static <T> Optional<T> empty();
    
    // 获取数据
    public T get();
    
    // 保存数据,但是不允许出现null
    public static <T> Optional<T> of(T value); // 如果在保存数据的时候存在null,则会抛出NullPointerException异常
    
    // 保存数据,允许为空
    public static <T> Optional<T> ofNullable(T value);
    
    // 数据为空的时候返回其他数据
    public T orElse(T other);
    
  • 在所有引用数据类型的操作处理之中,null是一个很重要的技术问题,所以JDK1.8后提供Optional类提供帮助,Optional在日后进行项目开发中使用次数会很多

ThreadLocal类

  • 这个类是在开发中特别重要的类,主要解决核心资源与多线程并发访问的处理情况

  • 来看一个单线程的程序处理:

    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 String getInfo() {
            return info;
        }
    
        public void setInfo(String info) {
            this.info = info;
        }
        
    }
    public class ThreadLocalDemo {
    
        public static void main(String[] args) {
            Message msg = new Message();
            msg.setInfo("周海林真帅!");
            Channel.setMessage(msg);
            Channel.send();
        }
    
    }
    
  • 多线程的影响:

    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 String getInfo() {
            return info;
        }
    
        public void setInfo(String info) {
            this.info = info;
        }
    
    }
    public class ThreadLocalDemo {
    
        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();
    
        }
    
    }
    
    // 执行结果
    【消息发送者B消息发送】第三个线程的消息
    【消息发送者A消息发送】第三个线程的消息
    【消息发送者C消息发送】第三个线程的消息
    

    出现了数据不同步的现象,在本程序中,在保持Channel核心结构不改变的情况下,需要考虑每个线程的独立操作问题。在这样的情况下,对于Channel类而言除了要保留要发送的消息之外,还要存放对每个线程的标记,这时候我们就可以使用ThreadLocal类来存放数据。

  • 在ThreadLocal里面提供如下操作方法:

    // 构造方法
    public ThreadLocal();
    
    // 设置数据
    public void set(T value);
    
    // 取出数据
    public T get();
    
    // 删除数据
    public void remove();
    
  • 解决线程同步问题:

    class Channel {
    
        private static final ThreadLocal<Message> THREAD_LOCAL = new ThreadLocal<Message>();
    
        private Channel() {}
    
        public static void setMessage(Message m) {
            THREAD_LOCAL.set(m);
        }
    
        public static void send() {
            System.out.println("【" + Thread.currentThread().getName() + "消息发送】" + THREAD_LOCAL.get().getInfo());
        }
    }
    
    class Message {
    
        private String info;
    
        public String getInfo() {
            return info;
        }
    
        public void setInfo(String info) {
            this.info = info;
        }
    
    }
    public class ThreadLocalDemo {
    
        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();
    
        }
    
    }
    
    // 运行结果
    【消息发送者B消息发送】第二个线程的消息
    【消息发送者C消息发送】第三个线程的消息
    【消息发送者A消息发送】第一个线程的消息
    

    每一个线程通过ThreadLocal只允许保存一个数据,开发中它可以作为资源引用传递多线程安全问题解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值