Java并发编程三 线程间通信

Java并发编程三 线程间通信

线程间通信:多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。就是多个线程在操作同一份数据时, 避免对同一共享变量的争夺。

1.wait/notify

使用wait/notify方法实现线程间通信(wait/notify为Object方法)

  • wait和notify必须配合synchronized关键字使用
  • wait释放锁,notify不释放锁
/**
 * wait/notify 示例
 * Created by lyyz on 18-5-9.
 */
public class SyncTest {
    private volatile List<String> list = new ArrayList<String>();

    public void add(){
        list.add("aaaa");
    }
    public int getSize(){
        return list.size();
    }

    public static void main(String[] args) {
        //lock 锁
        //wait/notify 必须和synchronized 配合使用
        final Object lock = new Object();
        final SyncTest syncTest = new SyncTest();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    try {
                        for (int i=0;i<10;i++){
                            syncTest.add();
                            System.out.println(syncTest.getSize());
                            Thread.sleep(500);
                            if (syncTest.getSize()==5){
                                System.out.println("t1 notify t2");
                                //notify 唤醒等待池中的线程但不释放锁 ,等待池中的线程进入锁池状态,争夺lock锁
                                lock.notify();
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    if(syncTest.getSize()!=5){
                        try {
                            //wait让当前线程进入等待状态,释放持有锁 程序计数器会记录当前的指令的位置,等其他线程唤醒后 继续从当前指令位置继续执行
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("t2 run");
                }


            }
        },"t2");

        t2.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t1.start();
    }
}

2.ThreadLocal

ThreadLocal一般称为线程本地变量,它是一种特殊的线程绑定机制,将变量与线程绑定在一起,为每一个线程维护一个独立的变量副本。通过ThreadLocal可以将对象的可见范围限制在同一个线程内。
ThreadLoal通过查看源码可知,其实就是将每一个线程的变量存储到一个Map里

 public void set(T value) {
    Thread t = Thread.currentThread();//1.首先获取当前线程对象
        ThreadLocalMap map = getMap(t);//2.获取该线程对象的ThreadLocalMap
        if (map != null)
            map.set(this, value);//如果map不为空,执行set操作,以当前threadLocal对象为key,实际存储对象为value进行set操作
        else
            createMap(t, value);//如果map为空,则为该线程创建ThreadLocalMap
    }

猜你喜欢

转载自blog.csdn.net/oyueyang1/article/details/80256496