【JDK】ThreadLocal类-解决核心资源多线程并发资源访问

       多线程开发中特别重要的类(解决了核心资源多线程并发资源访问的处理情况)

单线程分析范例

public class ThreadLocalTest {
    public static void main(String[] args) {
        Message message =new Message();//实例化消息主体对象
        message.setInfo("123123");//设置要发送的内容
        Channel.setMessage(new Message());//设置要发送的消息
        Channel.send();//发送消息
    }
}
class Message {//要发送的消息体
    private String info;

    public void setInfo(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }
}

class Channel {//消息的发送通道
    private static Message message;

    public static void setMessage(Message m) {
        message = m;
    }

    public static void send() {//发送消息
        System.out.println("【消息发送】" + message.getInfo());// }

    }
}

       上面的程序时采用单线程的模式来处理的 。如果在多线程的状态下能否实现完全一致的效果呢?为此以下将启动三个线程进行处理。

范例:多线程的影响:

public class ThreadLocalTest {
    public static void main(String[] args) {
        new Thread(() -> {
            Message message = new Message();//实例化消息主体对象
            message.setInfo("第一个线程的消息");//设置要发送的内容
            Channel.setMessage(message);//设置要发送的消息
            Channel.send();//发送消息
        }, "消息发送者A").start();
        new Thread(() -> {
            Message message = new Message();//实例化消息主体对象
            message.setInfo("第二个线程的消息");//设置要发送的内容
            Channel.setMessage(message);//设置要发送的消息
            Channel.send();//发送消息
        }, "消息发送者B").start();
        new Thread(() -> {
            Message message = new Message();//实例化消息主体对象
            message.setInfo("第三个线程的消息");//设置要发送的内容
            Channel.setMessage(message);//设置要发送的消息
            Channel.send();//发送消息
        }, "消息发送者C").start();
    }
}

class Message {//要发送的消息体
    private String info;

    public void setInfo(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }
}

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());// }
    }
}

       多个线程同时发送消息的时候,消息之间产生了影响。同步的问题出现了。(一个线程的东西被另一个线程取出来了)

       在保持Channel(所有发送的通道)核心结构不改变的情况下,需要考虑每个线程的独立操作问题。那么在这样的情况下就发现对于Channel类而言,除了要保留有发送的消息之外,还应该多存放有一个每一个线程的标记(当前线程)。解决方法:用ThreadLocal类来存放数据。在ThreadLocal类里面提供有如下方法:

  • 构造方法:public ThreadLocal();
  • 设置数据:public void set(T value);
  • 取出数据:public T get();
  • 删除数据:public void remove();

       ThreadLocal存有两个对象:一个是线程对象currentThread,一个是数据对象。

       所有的数据都应被存放入ThreadLocal中。所有的数据操作都是通过ThreadLocal。

范例:解决线程同步问题

public class ThreadLocalTest {
    public static void main(String[] args) {
        new Thread(() -> {
            Message message = new Message();//实例化消息主体对象
            message.setInfo("第一个线程的消息");//设置要发送的内容
            Channel.setMessage(message);//设置要发送的消息
            Channel.send();//发送消息
        }, "消息发送者A").start();
        new Thread(() -> {
            Message message = new Message();//实例化消息主体对象
            message.setInfo("第二个线程的消息");//设置要发送的内容
            Channel.setMessage(message);//设置要发送的消息
            Channel.send();//发送消息
        }, "消息发送者B").start();
        new Thread(() -> {
            Message message = new Message();//实例化消息主体对象
            message.setInfo("第三个线程的消息");//设置要发送的内容
            Channel.setMessage(message);//设置要发送的消息
            Channel.send();//发送消息
        }, "消息发送者C").start();
    }
}

class Message {//要发送的消息体
    private String info;

    public void setInfo(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }
}

class Channel {//消息的发送通道
    private static final ThreadLocal<Message> THREAD_LOCAL = new ThreadLocal<>();//很少会让你重新实例化,所以直接final


    public static void setMessage(Message message) {
        THREAD_LOCAL.set(message);
    }

    public Message getMessage() {
        return THREAD_LOCAL.get();
    }

    public static void send() {//发送消息
        System.out.println("【" + Thread.currentThread().getName() + "消息发送】" + THREAD_LOCAL.get().getInfo());// }

    }
}

       每一个线程通过ThreadLocal只允许保存一个数据。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值