Object类相关api(相关的方法一定是当前线程在获取了对应的锁对象才能调用,否则会抛出异常)

  o.wait() :锁对象调用该方法使当前线程进入等待状态,并立刻释放锁对象,直到被其他线程唤醒进入等锁池。

  o.wait(long) :锁对象调用该方法使当前线程进入等待状态,同时释放锁对象。但是超过等待的时间后线程会自动唤醒,或者被其他线程唤醒,并进入等锁池中。

  o.wait(long,int) :和o.wait(long)方法一样,如果int参数大于0则前面的long数字加1

  o.notify():随机唤醒一个处于等待中的线程(同一个等待阻塞池中)

  o.notifyAll():唤醒所有等待中的线程(同一个等待阻塞池中)

Thread类的相关api

  Thread.currentThread():返回对当前线程对象的引用

  Thread.interrupted():检测当前线程是否已经中断(调用该方法后后就将该线程的中断标志位设置位false,所以连续两次调用该方法第二次肯定时false)

  Thread.sleep(long millis):使当前线程睡眠(不会释放锁对象,可以让其他线程有执行的机会)

  Thread.yield():使当前线程放弃cpu的执行权(有可能立刻又被重新选中继续执行,只可能给优先级更高的线程机会)

  t.getId():返回该线程的id

  t.getName():返回该线程的名字

  t.getPriority():返回该线程的优先级

  t.getState():返回该线程的状态

  t.getThreadGroup():返回该线程所属的线程组

  t.interrupt():将该线程中断(实际并不会中断,只是将中断标志设置为true),如果线程正处在sleep(),join(),wait()方法中时(也就是正在阻塞中)调用该方法,该方法会抛出异常。

  t.interrupted():检测该线程是否已经中断(对中断标志位不作处理)

  t.isAlive():检测该线程是否还活着

  t.isDaemon():检测该线程是否为守护线程

  t.isInterrupted():检测该线程是否已经中断

  t.join():在a线程中调用b.join(),则a线程阻塞,直到b线程执行完

  t.join(long millis):和上面的方法一样,不过a线程阻塞的时间根据long的大小有关,如果达到设定的阻塞时间,就算b线程没有执行完,a线程也会被唤醒。

JDK5之后java.uti.concurrent包下面的一些工具类方便开发

  1、线程池

    ①为什么需要线程池? ------- 主要是为了重复利用线程资源,减少系统在创建和销毁线程上所花的时间和开销;同时也可以限制资源过多,防止出现OOM或执行效率下降

    ②如何获取线程池?

      在jdk5及以上版本中,使用java.util.concurrent.Executors类来创建线程池,该类提供了很多静态方法来创建线程池ExecutorService。

      1、Executors.newFixedThreadPool(int) 创建一个最大规模固定的线程池,如果当前线程不够用且没有超过线程池限制数量,则创建新的线程。如果线程池已满,则会将任务放入等待队列。

      2、Executors.newCachedThreadPool 创建一个最大规模可为Integer.MAX_VALUE 的可缓存的线程池。如果当前线程不够用就增加线程池中的线程数,如果当前线程池中线程过多,则会回收空的线程。

      3、Executors.newSingleThreadExecutor创建一个单线程的线程池,确保任务串行

      4、Executors.newScheduledThreadPool 创建一个固定大小的线程池,以延迟或者固定周期的方式执行,类似于定时器。

    ③执行任务和关闭线程池

      e.execute(Runnable r) :执行任务无返回值

      e.submit(Runnable r) :执行任务返回Future<?> ,实际上是null

      e.submit(Runnable r,T result) : 执行任务返回Future<T>

      e.submit(Callable c) :执行返回Future<?>

      e.invokeAny(Collection<? extends Callable<T> > c):随机执行集合中的一个任务,返回T。如果其中一个任务执行结束(或者抛了一个异常),其他 Callable 将被取消。

      e.invokeAll(Collection<? extends Callable<T> >  c):执行集合中所有的任务,返回List<Future<T>>

      e.shutdown():调用该方法后线程池立刻变成shutdown状态,不能再往线程池中增加新的任务否则将会抛出RejectedExecutionException异常,等所有进入队列的任务都执行完毕后关闭线程池

      e.shutdownNow():调用该方法后,线程池立刻变成stop状态,停止接受新的任务,并且试图停止所有正在执行的任务(使用的是Thread.interrupt()方法,不一定能中断正在执行的线程),不会执行等待队列中的任务,然后关闭线程池。

  

public class Test7 {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
//获取当前系统cpu的数目
int availableProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(availableProcessors);
fixedThreadPool.execute(new MyThread7());
fixedThreadPool.shutdown(); ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
Future<?> future = singleThreadExecutor.submit(new MyThread7());
Future<?> future2 = singleThreadExecutor.submit(new MyThread8());
System.out.println("future: "+future.get());
System.out.println("future2: "+future2.get());
singleThreadExecutor.shutdown(); ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
String result = "这是result";
Future<String> submit = cachedThreadPool.submit(new MyThread7(),result);
System.out.println("..."+submit.get());
cachedThreadPool.shutdown(); ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(availableProcessors);
//初始延迟3秒钟,只执行一次
scheduledThreadPool.schedule(new MyThread8(), 3, TimeUnit.SECONDS );
//初始延迟2秒中,每5秒执行一次
scheduledThreadPool.scheduleWithFixedDelay(new FixedDelay(), 2, 5, TimeUnit.SECONDS);
//初始延迟1秒钟,每4秒中执行一次
scheduledThreadPool.scheduleAtFixedRate(new FixedRate(), 1, 4, TimeUnit.SECONDS); Thread.sleep(20000);
scheduledThreadPool.shutdown();
}
} class MyThread7 implements Runnable{ @Override
public void run() {
System.out.println("执行代码:"+System.currentTimeMillis()/1000);
} } class MyThread8 implements Callable<String>{ @Override
public String call() {
System.out.println("执行代码:"+System.currentTimeMillis()/1000);
return "执行完成";
} } class FixedDelay implements Runnable{ @Override
public void run() {
System.out.println("FixedDelay执行代码:"+System.currentTimeMillis()/1000);
} }
class FixedRate implements Runnable{ @Override
public void run() {
System.out.println("FixedRate执行代码:"+System.currentTimeMillis()/1000);
} } 执行结果:
执行代码:1523348201
执行代码:1523348201
future:  null
执行代码:1523348201
future2:  执行完成
执行代码:1523348201
...这是result
FixedRate执行代码:1523348202
FixedDelay执行代码:1523348203
执行代码:1523348204
FixedRate执行代码:1523348206
FixedDelay执行代码:1523348208
FixedRate执行代码:1523348210
FixedDelay执行代码:1523348213
FixedRate执行代码:1523348214
FixedRate执行代码:1523348218
FixedDelay执行代码:1523348218

   ④ThreadPoolExecutor学习

      其实通过源码可知newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor 三种线程池的创建都是通过调用如下的方法来创建的。

  public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
int maximumPoolSize,//最大线程池大小
long keepAliveTime,//线程执行完成后在线程池中的缓存时间,也就是线程空闲多长时间后会被回收
TimeUnit unit,//时间单位TimeUnit.SECONDS
BlockingQueue<Runnable> workQueue,//线程缓冲队列,当线程池线程运行超过一定线程时并满足一定的条件,待运行的线程会放入到这个队列  
ThreadFactory threadFactory,//线程工厂,用来创建线程  
RejectedExecutionHandler handler//当缓冲队列也放不下线程时的拒绝策略  
  ){
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

  线程池总结:

  ThreadPoolExecutor对象初始化时,不创建任何执行线程,当有新任务进来时,才会创建线程来执行任务。当目前执行线程的总数小于核心线程大小时,所有新加入的任务,都会创建新线程来处理。当目前执行线程的总数大于或等于核心线程时,所有新加入的任务,都放入任务缓存队列中。当目前执行线程的总数大于或等于核心线程,并且缓存队列已满,同时此时线程总数小于线程池的最大规模,那么创建新线程,协助处理新的任务。当所有线程都在执行,线程池大小已经达到上限,并且缓存队列已满时,就rejectHandler拒绝新的任务。

  

  2、BlockingQueue:阻塞队列。

    下面是接口中一些常见的方法:BlockingQueue中不能插入null值,否则会抛出NullPointerException。

  

    ①ArrayBlockingQueue:有界的阻塞队列,其内部是通过数组实现,

    ②DelayQueue:无界的阻塞延时队列,加入该队列的元素需要实现Delayed接口,实现该接口的元素会有一个过期时间,只有过期的元素才能被取出。队列中元素会根据过期的先后顺序排序

    ③LinkedBlockingQueue:通过链式结构对元素进行储存,该链式结构可以设置存储上限,如果没有则用Integer.MAX_VALUE作为上限。

    ④PriorityBlockingQueue:优先级队列,加入该队列的元素必须实现Comparable接口,因为队列会根据compare()方法来对元素进行排序。

    ⑤SynchronousQueue:同步队列,该队列只能容纳一个元素,如果队列中已经有元素,则新加入的元素会阻塞。

    ⑥BlockingDeque:阻塞双端队列,可以将元素放入队列两端或从两端取出元素,该接口继承了BlockingQueue,实现类为LinkedBlockingDeque。

    

  3、java.util.concurrent.ConcurrentHashMap:和java.util.HashTable类似,但是ConcurrentHashMap拥有更好的并发性能。它在写入数据的时候不会将整个ConcurrentHashMap锁住,而是将写入的部分锁住。

  4、CountDownLatch:闭锁是一个并发构造,它允许一个或多个线程等待一系列的操作完成。CountDownLatch初始化时需要给定一个数量,闭锁调用await()方法可以使线程进入等待状态,该闭锁每调用一次countDown()就会将数量减1,当数量减为0后,所有的等待线程就会被唤醒。

  4、java.util.concurrent.CyclicBarrier:栅栏是一种类的同步机制,可以实现所有线程运行到某处后等待(通过调用await()方法),直到满足了所需的数量,才会一起释放去继续执行。当然也可以设定等待时间,那样即使没有达到数量也会继续执行。类似于约人一起去玩,先在某个地方一起集合,然后一起去。这是可以重复使用的。

  5.每次CyclicBarrier都支持栅栏行动,当最后一个线程都运行到栅栏时,就会执行该行动。CyclicBarrier行动就是一个线程。

  6、交换机java.util.concurrent.Exchanger:表示两个线程可以交换一类对象的汇合点,通过exchange(o)方法来交换对象。

  7、信号量java.util.concurrent.Semaphore:它是一个计数信号量,主要用于防止超过N个线程同时执行一块代码,或者进行两个线程之间发送信号。它主要有两个方法,require()和release()分别用来获取许可和释放许可。

  8、java.util.concurrent.locks.Lock:一个类似于 synchronized 块的线程同步机制。但是 Lock 比 synchronized 块更加灵活、精细。实现类java.util.concurrent.locks.ReentrantLock

  9、java.util.concurrent.locks.ReadWriteLock  :读写锁,它能够允许多个线程在同一时间对某特定资源进行读取,但同一时间内只能有一个线程对其进行写入。实现类 java.util.concurrent.locks.ReentrantReadWriteLock

  10、ForkJoinPool:其作用和ExecutorService差不多,但是其可以对任务进行分叉和合并

  11、AtomicBoolean、AtomicInteger、AtomicLong :数据具有原子性,并且增加了一些操作的方法。

  12、AtomicReference提供了一个可以被原子性读和写的对象引用变量

    

java多线程api的更多相关文章

  1. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  2. Java多线程--线程及相关的Java API

    Java多线程--线程及相关的Java API 线程与进程 进程是线程的容器,程序是指令.数据的组织形式,进程是程序的实体. 一个进程中可以容纳若干个线程,线程是轻量级的进程,是程序执行的最小单位.我 ...

  3. java多线程核心api以及相关概念(一)

    这篇博客总结了对线程核心api以及相关概念的学习,黑体字可以理解为重点,其他的都是我对它的理解 个人认为这些是学习java多线程的基础,不理解熟悉这些,后面的也不可能学好滴 目录 1.什么是线程以及优 ...

  4. Java多线程基础知识篇

    这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...

  5. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  6. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  7. java 多线程 1 线程 进程

    Java多线程(一).多线程的基本概念和使用 2012-09-10 16:06 5108人阅读 评论(0) 收藏 举报  分类: javaSE综合知识点(14)  版权声明:本文为博主原创文章,未经博 ...

  8. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  9. java多线程系类:JUC线程池:03之线程池原理(二)(转)

    概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...

随机推荐

  1. MySQL官方教程及各平台的安装教程和配置详解入口

    官方文档入口: https://dev.mysql.com/doc/ 一般选择MySQL服务器版本入口: https://dev.mysql.com/doc/refman/en/ 在右侧有版本选择: ...

  2. HTML5-SVG-基础篇

    什么是SVG? SVG 指可伸缩矢量图形 (Scalable Vector Graphics) SVG 用于定义用于网络的基于矢量的图形 SVG 使用 XML 格式定义图形 SVG 图像在放大或改变尺 ...

  3. 解决Docker容器中不能用vim编辑文件

    更新来源: apt-get update 安装vim apt-get install -y vim 参考链接:https://blog.csdn.net/wangxinxinsj/article/de ...

  4. BZOJ2738矩阵乘法——整体二分+二维树状数组

    题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入   第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5 ...

  5. 洛谷AT2046 Namori(思维,基环树,树形DP)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...

  6. ftp利用脚本添加本地用户

    指定用户名,家目录,密码,顺序不可颠倒.eg: sh 脚本名 用户名 家目录 密码 #!/bin/bash # set -e ] //判断给定参数是否为三个 homepath=$ password=$ ...

  7. python实用脚本集

    iScript 是Github上 PeterDing 大神写的一个脚本集,由多数的 python 脚本和少数GM脚本组成. 含有以下几个脚本: xiami.py - 下载或播放高品质虾米音乐(xiam ...

  8. Linux里文件和文件夹权限的含义

      文件的权限: r : 可以读取此文件的实际内容. w: 可以编辑.新增或者是修改该文件的内容(但不含删除该文件),如果没有r权限,无法w. x : 该文件具有被系统执行的权限,可以删除. 文件夹的 ...

  9. php记录

    PHP反射API 反向代理使用https协议,后台Tomcat使用http,redirect时使用错误协议的解决办法 多记几个导出公式,手中有粮,心中不慌 哈哈哈 PhpExcel中文帮助手册 Php ...

  10. CodeForces 407C 组合数学(详解)

    题面: http://codeforces.com/problemset/problem/407/C 一句话题意:给一个长度为n的序列g,m次操作,每次操作(l,r,k)表示将g[l]~g[r]的每个 ...