在多线程学习的过程中涉及的方法和接口特别多,本文就详细讲解下经常使用方法的作用和使用场景。

1.sleep()方法。

     当线程对象调用sleep(time)方法后,当前线程会等待指定的时间(time),并让出cpu执行权,但是它的监控状态依然当前对象的保持者(不会释放对象锁),当指定的时间到了又会自动恢复运行状态。

2.wait()和notify()/notifyAll()方法。

    wait()和notify()、notifyAll()方法的调用都必须在synchronized修饰的方法或者代码块中调用,使用过程中必须获得对象锁,否则会抛出java.lang.IllegalMonitorStateException的异常。

执行wait()方法,会使当前线程的状态变为阻塞状态并交出对象锁。

执行notify()方法,会随机挑选一个当前对象阻塞队列中的线程并将状态变为就绪状态。

执行notifyAll()方法,会将当前对象阻塞队列中的所有线程的状态变为就绪状态。

    wait()和notify()、notifyAll()为什么都是Object类中的方法。因为synchronized中的这把锁可以是任意对象,所以任意对象都可以调用wait()和notify();所以wait和notify属于Object。

专业说:因为这些方法在操作同步线程时,都必须要标识它们操作线程的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法是定义在object类中。

3.join()方法。

 在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。并且join()方法是会释放锁的,因为底层使用 wait() 方法来实现的。

4.yield()方法。

   yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。(不会释放锁)

因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。

4.interrupt()和isInterrupted()/interrupted()方法。

  thread.interrupt(),当thread对象变为中断状态,interrupt()并不能中断在运行中的线程,它只能改变中断状态而已。

thread.interrupted(),判断当前线程对象的状态是否为中断状态,内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态。

thread.isInterrupted(),判断当前线程对象的状态是否为中断状态,不会重置当前线程的中断状态。

5.CountDownLatch类。

CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。

 CountDownLatch countDownLatch=new CountDownLatch(5);//CountDownLatch初始化等待5个线程,等待5个线程执行完主线程再执行。

           countDownLatch.await();//主线程阻塞

           countDownLatch.await(1000, TimeUnit.SECONDS);//主线程阻塞,超时后count还没有为0的话,主线程执行。

           countDownLatch.countDown();//将count值减1,当count值为0后,主线程执行。

使用场景:

①某一线程在开始运行前等待n个线程执行完毕。将 CountDownLatch 的计数器初始化为n :new CountDownLatch(n) ,每当一个任务线程执行完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await()的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。

②实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的
CountDownLatch 对象,将其计数器初始化为 1 :new CountDownLatch(1) ,多个线程在开始执行任务前首先
coundownlatch.await(),当主线程调用 countDown() 时,计数器变为0,多个线程同时被唤醒。

③死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

6.LockSupport类。

  LockSupport可以起到和wait()一样的作用。在没有LockSupport之前,线程的挂起和唤醒咱们都是通过Object的wait和notify/notifyAll方法实现。

public class TestObjWait {

    public static void main(String[] args)throws Exception {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
int sum = 0;
for(int i=0;i<10;i++){
sum+=i;
}
LockSupport.park();//阻塞线程
System.out.println(sum);
}
});
A.start();
//睡眠一秒钟,保证线程A已经计算完成,阻塞在wait方法
Thread.sleep(1000);
LockSupport.unpark(A);//唤醒阻塞线程
}
}

总结一下,LockSupport比Object的wait/notify有两大优势

①LockSupport不需要在同步代码块里 。所以线程间也不需要维护一个共享的同步对象了,实现了线程间的解耦。

②unpark函数可以先于park调用,所以不需要担心线程间的执行的先后顺序。

java多线程中用到的方法详细解析的更多相关文章

  1. [转]Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  2. 转:Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  3. Java多线程学习(吐血超详细总结)

    本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的 ...

  4. [转]Java多线程学习(吐血超详细总结)

    转自:http://www.mamicode.com/info-detail-517008.html 本文主要讲了Java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法. ...

  5. Java多线程学习(吐血超详细总结)(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但 ...

  6. (转)Java多线程学习(吐血超详细总结)

    本文转自:http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能 ...

  7. 转:Java多线程学习(吐血超详细总结)

    版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 目录(?)[+] 林炳文Evankaka原创作品.转载请注明出处http: ...

  8. Java多线程学习(吐血超详细总结)转自博主林炳文Evankaka

    文章由林炳文Evankaka原创.转载自http://blog.csdn.net/evankaka 写在前面的话:此文只能说是Java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果 ...

  9. java 多线程中的wait方法的详解

    java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...

随机推荐

  1. EasyHLS实现将IPCamera摄像机的RTSP流转成HLS(ts+m3u8)直播输出

    本文转自:http://www.cnblogs.com/babosa/p/6033039.html EasyHLS EasyHLS是EasyDarwin开源流媒体团队开发的一款HLS打包库,接口非常简 ...

  2. LeetCode(83)Remove Duplicates from Sorted List

    题目 Given a sorted linked list, delete all duplicates such that each element appear only once. For ex ...

  3. SIP学习笔记 -- RFC 3261

    1.SDP (rfc 4566)    1)用于交换参数    2)内容分三部分Session description, Time description and Media description ...

  4. LVS的体系结构

    LVS集群的体系结构 章文嵩 (wensong@linux-vs.org) 转自LVS官方资料 2002 年 4 月 本文主要介绍了LVS集群的体系结构.先给出LVS集群的通用体系结构,并讨论了其的设 ...

  5. Flask内置命令行工具—CLI

    应用发现 flask命令在Flask库安装后可使用,使用前需要正确配置FLASK_APP环境变量以告知用户程序所在位置.不同平台设置方式有所不同. Unix Bash (Linux, Mac, etc ...

  6. 不使用库函数,编写函数int strcmp(char *source, char *dest) 相等返回0,不等返回-1【转】

    本文转载自:http://www.cppblog.com/mmdengwo/archive/2011/04/14/144253.aspx #include <stdio.h>#includ ...

  7. 在Linux中利用Service命令添加系统服务及开机自启动

    有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s                       在/etc/rc.d/rc*.d目录中建立/e ...

  8. java random配置修改

    不知道 报啥错的时候 ,改这个 vim /usr/java/latest/jre/lib/security/java.security 原值: securerandom.source=file:/de ...

  9. ssh整合 小例子

    实现了用户的查插删改操作. 原理:struts负责接收.分发请求.spring采用面向接口编程的思想整合整体框架,负责连接数据库.hibernate负责操作数据库语言. 思路: 1.配置struts的 ...

  10. Tkinter图片按钮

    imgBtn = tk.PhotoImage(file='test.png') tk.Button(image=imgBtn).pack() tk.mainloop() 转载,来源简书评论,地址:ht ...