`

Java核心技术卷I -- 第14章 多线程

阅读更多

1. Thread.sleep(long millis): 休眠制定的毫秒数。

2. 实现多线程的两种方法

    2.1 实现Runnable接口

        class BallRunnable implements Runnable {

            public void run() {  //需要try..catch来捕获异常

                try{

                    do something

                } catch (InterruptedException) {}

            }

        }

    2.2 继承Thread

        class MyThread extends Thread {

            public void run() {task code}

        }

    2.3 启动线程

        Ball b = new Ball();

        panel.add(b);

        Runnable r = new BallRunnable(b, panel);

        Thread t = new Thread(r);

        t.start();

        不要调用Thread类或者Runnable对象的run方法,直接调用只会在当前线程中执行任务,并不会启动新线程。

3. 中断线程

    JDK1.0 stop() 现在已经被弃用,现在使用interrupt方法来请求终止一个线程,步骤如下:

    Thread.currentThread().isInterrupted() //首先取得当前线程,然后调用isInterrupted()来判断给线程是否中断

    如果一个线程被阻塞,而调用isInterrupted() ,将会产生InterruptedException异常

    void interrupt(): 发送一个中断给一个线程,这个线程的中断状态将为True,如果当前线程被sleep调用,将抛出InterruptedException异常。常在catch(InterruptedException e) {Thread().currentThread().interrupt();}

    static boolean interrupted(): 检查当前线程是否被中断,调用它将清除该线程的中断状态

    boolean isInterrupted(): 检查线程是否被终止,而不会改变中断状态的值

4. 线程状态

    New(新生)、Runnable(可运行)、Blocked(被阻塞)、Dead(死亡)

    isAlive(): 如果线程已经启动并还没有被终止,返回true

    stop(): 停止线程。方法过时

    suspend(): 挂起当前线程的执行过程。方法过时

    resume(): 恢复线程。方法过时

    join(): 等待直到指定的线程死亡

    join(long millis): 等待直到指定的线程死亡或经过制定的毫秒数

5. 线程优先级

    线程优先级和系统有密切关系

    setPriority(int newPriority): 设置线程优先级。一般有Thread.MIN_PRIORITY(值为1)、NORM_PRIORITY(值为5)、MAX_PRIORITY(值为10) 

    static void yield(): 导致当前执行线程进入让步状态,如果有优先级不低于此线程的其他线程存在,那么这些线程将被调度。

6. 守护线程

    也成为后台线程 t.setDaemon(true); 此方法必须在线程开始之前被调用

7. 线程组

    可以把类似的线程加入一个线程组来便于统一操作

    String groupName = "myGroup";

    ThreadGroup g = new ThreadGroup(groupName);

    Thread t = new Thread(g, threadName);  //把一个线程加入到g线程组中

    g.activeCount();  //查明线程组中是否有线程处于可运行状态

    g.interrupt();  //中断线程组中所有的线程

8. 未捕获异常处理器

    线程run方法不能抛出任何被检查的异常,所以需要对一个线程安装一个处理器

    setDefaultUncaughtExceptionHandler()设置默认处理器,如果不设置,则为null

9. 同步

    两种方式,一种同步锁,一种使用Synchronized

    9.1 锁对象 - 显示锁

        private Lock bankLock = new ReentrantLock();

        bankLock.lock();

        try {do something;}

        finally {bankLock.unlock();}

    9.2 条件对象

        一个线程进入临界区,发现必须等待满足某个条件才能执行,那么就需要使用一个条件对象来实现。

        class Bank {

            private Condition sufficentFunds;    //定义条件对象

            public Bank() {

                sufficentFunds = bankLock.newConditon();    //从ReentrantLock对象中New一个Condition对象

            }

            public void transfer(int from, int to, int amount) {

                bankLock.lock();     //开始锁对象

                try {

                    while (acconts[from] < amount)

                        sufficentFunds.await();    //如果不满足条件,就进入阻塞状态

                    // transfer funds

                    sufficentFunds.signalAll();    //解除所有线程的阻塞状态

                }

                finally {bankLock.unlock();}

            }

        }

        await(): 等价于wait(),线程进入阻塞状态,当锁可获得,线程不能马上解除,直到另外一个线程调用同一条件上的signalAll方法。

        signalAll(): 等价于notifyAll(),解除阻塞状态,但是线程不会马上执行,还需要竞争锁。

        signal(): 等价于notify(),随机解除等待某个线程的阻塞状态。

    9.3 Synchronized     

        同步方法: Synchronized - 隐式锁

        同步块: 对单独代码块进行Synchronized

        同步实例域: volatile

            public boolean isDone() {return done;}

            private volatile boolean done;

10. 锁

    10.1 死锁

    10.2 公平锁

        Lock fairLock = new ReentrantLock(true);

    10.3 锁测试

        myLock.tryLock(): 尝试获得锁但不会发生阻塞,成功返回true

    10.4 读/写锁

        private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

        private Lock readLock = rwl.readLock();    //得到一个读操作可公用锁,排斥所有写操作

        private Lock writeLock = rwl.writeLock();    //得到一个写锁,排斥其他的读写操作

11. 阻塞队列

    11.1 4种阻塞队列

        ArrayBlockingQueue(int capacity)和ArrayBlockingQueue(int capacity, boolean fair): 制定容量和公平性设置的阻塞队列,用来循环数组。

        LinkedBlockingQueue()或LinkedBlockingQueue(int capacity): 构建一个无边界或者有容量的阻塞队列,由链表实现。

        DelayQueue(): 包含Delayed元素的无界的阻塞时间有限的阻塞队列

        Delayed.getDelay(TimeUnit unit): 得到该对象的延迟

        PriorityBlockingQueue(): 阻塞优先级队列

    11.2 队列方法

        add: 添加一个元素,队列满则抛出异常

        offer:添加一个元素,如果队列满返回false

        put: 添加一个元素,队列满则阻塞

        remove: 移除并返回队列头部的元素,队列空抛异常

        poll: 移除并返回队列头部的元素,队列空返回null

        take: 移除并返回队列头部的元素,队列空则阻塞

        element: 返回队列头部的元素,队列空抛异常

        peek: 返回队列头部的元素,队列空返回null

12. 线程安全的集合

    java.uti.concurrent提供两个集合: ConcurrentLinkedQueue和ConcurrentHashMap   

    ConcurrentHashMap.putIfAbsent(K key, V value): 将给定值和键联系起来

    ConcurrentHashMap.remove(K key, V value): 移除

    ConcurrentHashMap.replace(K key, V oldValue, V newValue): 新的值相关联

13. Callable和Future

    13.1 Callable相当于Runnable,但是有返回值

        class Counter implements Callable<Integer> {public Integer call()}    //定义Callable

    13.2 Future用来保存返回的结果

        Counter count = new Counter();

        FutureTask<Integer> task = new FutureTask(count);

        Thread t = new Thread(task);

        t.start(); 

        get(): 获取结果

        cancel(boolean mayInterrupt): 尝试取消任务运行,如果线程开始且mayInterrupt为true,那么被中断

        isCancelled(): 如果任务在完成之前被取消,返回true

        isDone(): 任务是否结束

14. 线程池 - 执行器

    14.1 线程池的使用

        newCachedThreadPool: 创建线程池,如果池中有空闲线程,则使用空闲线程,否则创建新线程

        newFixedThreadPool: 包含固定数量线程

        newSingleThreadExecutor: 只有一个线程的池,顺序执行

        以上3种,实现了ExecutorService接口。

        1. 调用Executors类中静态的newCachedThreadPool或newFixedThreadPool方法

            ExecutorService pool = Executors.newCachedThreadPool();

        2. 调用submit来提交一个Runnable或Callable对象

            MatchCounter counter = new MatchCounter(new File(directory), keyword, pool);    //MatchCounter是实现了Callable<Integer>

            Future<Integer> result = pool.submit(counter);    //提交返回的Callable对象

        3. 如果希望取消任务或者保存结果,那么就需要保存好Future对象

            result.get();

        4. 当不想提交任务的时候调用shutdown

            pool.shutdown();

        5. 得到线程池容量

            int ((ThreadPoolExecutor)pool).getLargestSize();

    14.2 预订执行

        newScheduledThreadPool: 为预定执行而构建的固定线程池

        newSingleThreadScheduledExcutor: 为预定执行而构建的单线程“池”

        以上2种,实现了ScheduledExecutorService接口

    14.3 控制线程组 - 把所有任务集中起来处理

        ArrayList<Callable<Integer>> tasks = ...;

        List<Future<Integer>> results = executor.invokeAll(tasks);

15. 同步器

分享到:
评论

相关推荐

    JAVA.2核心技术.卷I:基础知识(原书第7版).part1.rar

    全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件、部署应用程序和Applet、异常日志断言和调试、泛型程序设计、集合以及多线程等内容。 全书对Java...

    java2核心技术第I卷.基础知识(中文PDF完整版)

    全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件、部署应用程序和Applet、异常日志断言和调试、泛型程序设计、集合以及多线程等内容。 全书历经12...

    JAVA.2核心技术.卷I:基础知识(原书第7版).part2.rar

    全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件、部署应用程序和Applet、异常日志断言和调试、泛型程序设计、集合以及多线程等内容。 全书对Java...

    Java核心技术 卷I(原书第8版).Part1 pdf

    共分两个压缩包 此为第一个压缩包 第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 1.2.4 健壮性 1.2.5 安全性 ...第14章 多线程

    Java核心技术 卷I(原书第8版).part2 PDF

    共分为两个压缩包 此为第2个压缩包 第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 1.2.4 健壮性 1.2.5 安全性 ...第14章 多线程

    java 核心编程 java

    全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件、部署应用程序和Applet、异常日志断言和调试、泛型程序设计、集合以及多线程等内容。. 全书对Java...

    Java核心技术_第八版(英文原版).part1

    全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件、部署应用程序和Applet、异常日志断言和调试、泛型程序设计、集合以及多线程等内容。 全书历经12...

    Core Java. Volume I. Fundamentals, 8th Edition JAVA核心技术1基础知识

    更新到jdk 6平台,但和 第七版没有本质的区别 代码示例请到此地址下载:【corejava8代码示例】http://download.csdn.net/source/2366281 1 AN INTRODUCTION TO JAVA Java As a Programming Platform ...第14章 多线程

    Java核心技术_第八版(英文原版).part2

    全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件、部署应用程序和Applet、异常日志断言和调试、泛型程序设计、集合以及多线程等内容。 全书历经12...

    编程实践:Java进阶100例

    中文名: 编程实践:Java进阶100例 原名: 编程实践:Java进阶100例 别名: Java 作者: 李相国等. 译者: 李相国等. 图书分类: 软件 ...Java行业是一直被业界看重的既有...第十四章:桌面程序特效; 第十五章:网络编程

    新版Android开发教程.rar

    � Google 提供了一套 Java 核心包 (J2SE 5,J2SE 6) 的有限子集,尚不承诺遵守 Java 任何 Java 规范 , 可能会造 成J ava 阵营的进一步分裂。 � 现有应用完善度不太够,需要的开发工作量较大。--------------------...

    Java优化编程(第2版)

    第14章 ajax技术与web应用性能优化 14.1 了解ajax 14.2 通过ajax技术改善web应用性能 14.2.1 ajax技术实现 14.2.2 ajax技术性能优化实例 小结 第15章 其他优化话题 15.1 用weakhashmap屏蔽内存泄漏 15.2 优化java...

    JAVA.WEB服务.构建与运行

    1.10 多线程端点服务发布程序 27 1.11 下一章 30 第2章 全面了解wsdl 31 2.1 wsdl在web服务中的作用 31 2.2 wsdl文档结构 36 2.3 amazon e-commerce web服务 46 2.4 wsgen工具与jax-b工件(artifacts) 59 2.5 wsdl...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    Java常见面试题208道.docx

    面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...

    java视频教程Day01 免费

    11. Multi-Thread(多线程) 12. I/O and File (输入/输出流及文件) 13. Networking (网络编程) 以上教学过程中贯穿一个银行项目,根据每天所学的东西不断完善 J2EE部分 14. JDBC Overview and Using JDBC ...

    jsr80 java 访问 usb

    这个 API 提供了对多个物理 USB 设备的多线程访问,并支持本机和远程设备。具有多个接口的设备可以同时被多个应用程序(或者设备驱动程序)所访问,其中每一个应用程序(或者设备驱动程序)都占据一个不同的接口。该 API...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

Global site tag (gtag.js) - Google Analytics