Java——线程间的通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/beitacat/article/details/82319553

两个线程从初始化时,传入同一个对象,可发生通信。

使用static数据。

传入的参数可作为对象锁,多个线程竞争该对象锁。

1.使用wait/notify函数实现(等待/通知机制

等待/通知机制

wait()使当前执行代码的线程进行等待,将该线程置入“等待队列中(随时唤醒可执行状态)”;调用wait方法前,必须获取到该对象的对象级别的锁(wait/notify方法继承与Object类),即只能在同步方法或者同步块中调用该方法。执行之后,释放对象锁,并且能和其他线程一起竞争该锁。

带参数wait(Long)方法等待某一段时间内是否有线程对锁进行唤醒,如果超过则自动唤醒,long后继续执行程序。

notify()同样需要获取对象锁才能在同步方法或者同步块中调用该方法。该方法会通知可能在等待该对象锁的其他线程,如果有多个则随机挑选一个。执行完notify之后,不会立即释放锁,wait中的线程也不能立即获取锁,要等到执行notify方法的线程将程序执行完,即退出synchronized代码块。notify唤醒其他wait线程,如果对象一直没有调用notify函数,即使对象处于空闲,锁已经释放,wait线程也只能一直处于等待,直到该对象调用notify/notifyAll

notify随机通知一个线程唤醒,进入可执行状态,多次调用则唤醒多个线程。

notifyAll使所有的wait状态线程从等待状态进入可执行状态,此时优先级最高的线程最先执行,也可能随机执行。取决于虚拟机的实现。

2.生产者,消费者模式实现

3.join方法实现

使调用join的线程对象执行完毕run方法中的任务之后,才执行当前线程任务:

public static void main(String[] args){
    try{
        MyThread myThread = new MyThread();
        myThread.start();
        myThread.join();
        Sysotem.out.println("------主线程中的任务-----");
    }catch(Exception e){
    }
}

原本如果主线程中没有myThread.join(),输出函数也许会先于子线程执行完毕;加上join后,主线程将被无限期挂起,直到子线程执行完毕销毁后才继续执行。阻止被插入的线程的执行,先执行插入的线程。

join(Long),设置等待的时间,内部采用wait(Long)实现,具有释放锁的特点,所以调用之后会释放锁。

sleep(Long),也会等待再执行,不会释放锁。

4.ThrealLocal实现

ThreadLocal解决每一个线程都能绑定自己的值。存放着每个线程的私有数据。

public static ThreadLocal tl = new ThreadLocal()

tl.get()取值,默认第一次调用没有值返回null。可以继承ThreadLocal类,重写initailValue()方法,返回初始值。

tl.set()存值

哪个线程调用ThreadLocal对象及其函数,则对该线程的数据进行操作。main线程调用,操作main线程数据,若是在ThreadA线程的run中调用,则是操作A线程的数据。

使用InheritableThreadLocal类在让子线程从父线程中获取值,例如在main函数中创建新的进程,新的进程的run函数中调用InheritableThreadLocal对象,get函数获取main线程的数据。

猜你喜欢

转载自blog.csdn.net/beitacat/article/details/82319553