JAVA学习笔记(四十三)- ThreadLocal

死锁

/*
 * 死锁:多个线程使用不同的锁,每个线程都需要另一个线程持有的锁
 * 出现:同步的嵌套
 * 
 */
public class Test01 {
    public static void main(String[] args) {
        Tom tom = new Tom();
        Alice alice = new Alice();
        MyThread mt1 = new MyThread(tom, alice, true);
        MyThread mt2 = new MyThread(tom, alice, false);
        Thread th1 = new Thread(mt1);
        Thread th2 = new Thread(mt2);
        th1.start();
        th2.start();
    }
}

class MyThread implements Runnable {
    private Tom tom;
    private Alice alice;
    boolean flag;

    public MyThread(Tom tom, Alice alice, boolean flag) {
        this.tom = tom;
        this.alice = alice;
        this.flag = flag;
    }

    @Override
    public void run() {
        if (flag) {
            synchronized (tom) { // tom鎖
                tom.say();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (alice) { // alice鎖
                    tom.show();
                }
            }
        } else {
            synchronized (alice) { // alice鎖
                alice.say();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (tom) {// tom鎖
                    alice.show();
                }
            }
        }
    }

}

/*
 * tom需要笔
 */
class Tom {
    public void say() {
        System.out.println("给我笔");
    }

    public void show() {
        System.out.println("得到笔");
    }
}

/*
 * alice需要笔
 */
class Alice {
    public void say() {
        System.out.println("给我本子");
    }

    public void show() {
        System.out.println("得到本子");
    }
}

ThreadLocal

import java.util.Random;

/*
 * ThreadLocal
 * 为每个线程提供一个变量的副本,不同的线程获取的变量不同
 * 线程局部变量的含义,即产生的变量为某个线程所有,对此线程是局部的
 */
public class Test03 {
    public static void main(String[] args) {
        MyThread3 mt=new MyThread3();
        Thread th1=new Thread(mt, "线程一");
        Thread th2=new Thread(mt, "线程二");
        Thread th3=new Thread(mt, "线程三");
        Thread th4=new Thread(mt, "线程四");

        th1.start();
        th2.start();
        th3.start();
        th4.start();
    }
}

class MyThread3 implements Runnable {
    //创建一个线程局部变量,用于管理多线程要操作的对象
    private static ThreadLocal<Student> local=new ThreadLocal<Student>();

    //获取线程局部变量的方法
    public Student getStudent(){
        //第一次获取时,获取的值必须为空
        Student stu = local.get();
        if(stu==null){
            stu=new Student();//第一次获取对象时没有学生,所以需要手动创建一个对象
            local.set(stu);//将学生对象交由ThreadLocal管理
        }
        return stu;
    }

    @Override
    public void run() {
        Random r = new Random();
        int age = r.nextInt(100);
        //从ThreadLocal中获取本线程的学生对象
        Student stu=getStudent();
        stu.setAge(age);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "***"
                + stu.getAge());

    }

}

synchronized和ThreadLocal区别

import java.util.Random;

/*
 * synchronized和ThreadLocal区别
 * synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离
 */
public class Test02 {
    public static void main(String[] args) {
        Student stu=new Student();
        MyThread2 mt=new MyThread2(stu);
        Thread th1=new Thread(mt, "线程一");
        Thread th2=new Thread(mt, "线程二");
        th1.start();
        th2.start();
    }
}

class MyThread2 implements Runnable {
    private Student stu;

    public MyThread2(Student stu) {
        this.stu = stu;
    }

    @Override
    public void run() {
        while(true){
        Random r = new Random();
        int age = r.nextInt(100);
        synchronized (stu) {
            stu.setAge(age);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "***"
                    + stu.getAge());
        }
    }
    }

}

/*
 * 学生类
 */
class Student {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值