线程基本使用入门(一)

volatile关键字
最轻量的同步机制: 可以保证可见,但是不能保证原子。

//演示Volatile的提供的可见性
public class VolatileCase {
    private static boolean ready;
    private static int number;

    private static class PrintThread extends Thread{
        @Override
        public void run() {
            System.out.println("PrintThread is running......");
            while (!ready);
            System.out.println("number = "+number);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new PrintThread().start();
        Thread.sleep(1000);
        number=51;
        ready=true;
        Thread.sleep(5000);
        System.out.println("main is ended");
    }
}

结果:
在这里插入图片描述
说明主程序中ready做的修改没有被线程看到。

现在把ready改为如下:

private volatile static boolean ready;

结果:
在这里插入图片描述
说明加了volatile之后,主线程的修改能被看见,但是它只能保证可见性,不能保证原子性,即不能保证某个数据在多个线程下同时写的时候的安全。

应用场景:一写多读。

ThreadLocal辨析
ThreadLocal : 每个线程都有变量的副本,实现线程的隔离。
Spring在实现事物的时候要借助ThreadLocal。
下面来看看如下例子:

public class UseThreadLocal {
    private static ThreadLocal<Integer> threadLocal=new ThreadLocal<Integer>(){
        @Override
        protected Integer initialValue() {
            return 1;
        }
    };

    /*
    运行三个线程
     */
    public void StartThreadArray(){
        Thread[] runs=new Thread[3];
        for(int i=0;i<runs.length;i++){
            runs[i]=new Thread(new TestThread(i));
        }
        for (int i=0;i<runs.length;i++){
            runs[i].start();
        }
    }

    /*
    类说明:测试线程,线程的工作是将ThreadLocal变量的值变化,并写回,看看线程之间是否会相互联系
     */
    public static class TestThread implements Runnable{
        int id;
        public TestThread(int id){
            this.id=id;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+".start");
            Integer s=threadLocal.get();
            s=s+id;
            threadLocal.set(s);
            System.out.println(Thread.currentThread().getName()
                            +":"+threadLocal.get());

        }
    }

    public static void main(String[] args) {
        UseThreadLocal test=new UseThreadLocal();
        test.StartThreadArray();
    }
}

结果如下:
在这里插入图片描述
说明能让每个线程有独立的副本。

如果定义多个ThreadLocal会放到map里面。
每个线程有个自己的ThreadLocalMap。

Entry(ThreadLocal<?> k, Object v){
		super(k);
		value=v;
}

在这里插入图片描述

引用:强引用、软引用、弱引用、虚引用
Object o=new Object(); //强引用
SoftRefence 要发生溢出 软引用
所有的弱引用都在ThreadLocal 所标志出来:extends WeakReference<ThreadLocal<?>> 。意味着只要发生垃圾回收,这个thread变量就一定会被回收。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值