Java总结<三>多线程
2012-10-07 17:45
330 查看
基本概念:
并发性和并行性:
并发性指的是同一时刻只能有一条指令执行,但是多个进程指令被快速轮换执行
并行性是指同一时刻,有多条指令在多个处理器上同时执行,使得在宏观上具有多个进程同时执行的结果
临界区:修改共享资源的代码区
1、线程实现有三种方式:
(1)类ThreadName(引用为a)继承Thread,然后调用a.start();
(2)类ThreadName(引用为b)实现接口Runnable,然后new Thread(b).start();
(3)类ThreadName(引用为c)实现接口Callable<Integer>,然后call方法作为执行体,会有返回值。
声明FutureTask<Integer> task = new FutureTask<Integer>(c);
Thead thread = new Thread(task).start();
一般采用实现接口的方式实现,有以下有优点:
使用实现Runnable接口和Callable接口的可以继续实现其他接口或继承
在这种方式下,多个线程可以共享一个target对象(共享线程类的实例属性),所以非常适合多个相同线程处理同一份资源的情况
实现Runnable和Callable的最大区别在于Callable是调用call方法,有返回值的
2、线程的生命周期:新建、就绪、运行、阻塞、死亡
线程在以下三种方式之一结束后就会处于死亡状态
(1)run()方法执行完成,线程正常结束
(2)线程抛出一个未捕获的Exception或Error
(3)直接调用该线程的stop()方法来结束该线程——该方法很容易导致对象受破坏,通常不推荐使用
3、线程的一些方法
join():等待另一线程执行完才执行
sleep():睡眠,不会释放对该同步监视器的锁定
wait():等待直到有notify()或者notifyAll()的调用,会释放对该同步监听器的锁定
yield():暂时放弃cpu占用,变为就绪,不会释放对该同步监视器的锁定
notify():从wait()后的线程中,调度其中一个线程
notifyAll():唤醒所有wait()后的线程
suspend():将该线程挂起,不会释放对该同步监视器的锁定。直到有resume(),但是这种方式会引起死锁,应尽量避免使用
4、线程同步
(1)使用synchronized同步代码块或同步方法
(2)使用同步锁Lock
5、线程的通信
(1)传统的方式是使用上面3的方法进行通信
(2)如果使用了同步锁Lock,则不能使用wait()、notify()、notifyAll()进行线程通信,这时需要使用Condition
(3)是要哄阻塞队列控制线程的通信
6、线程池
7、Daemon Thread的特点:如果所有的前台线程都死亡,后台线程会自动死亡,然后虚拟机也退出,基于这样的特点,有些功能是不合适用守护线程来实现的
创建守护线程的过程应该注意:setDaemon(true)必须在start()方法之前调用。否则会引发IllegalThreadStateException异常
8、sleep方法和yield方法的区别:
(1)sleep方法暂停当前线程,会给其他线程执行机会,不会理会其他线程的优先级;但是yield方法只会给优先级相同或更高的线程执行的机会。所以yield完全有可能变成就绪后直接就又重新执行
(2)sleep方法声明抛出了InterruptedException异常,所以调用sleep方法要么捕捉该异常,要么显示声明抛出该异常。而yield方法则没有声明抛出任何异常
(3)sleep方法比yield方法有更加好的移植性,通常不要依靠yield来控制并发线程的执行
并发性和并行性:
并发性指的是同一时刻只能有一条指令执行,但是多个进程指令被快速轮换执行
并行性是指同一时刻,有多条指令在多个处理器上同时执行,使得在宏观上具有多个进程同时执行的结果
临界区:修改共享资源的代码区
1、线程实现有三种方式:
(1)类ThreadName(引用为a)继承Thread,然后调用a.start();
(2)类ThreadName(引用为b)实现接口Runnable,然后new Thread(b).start();
(3)类ThreadName(引用为c)实现接口Callable<Integer>,然后call方法作为执行体,会有返回值。
声明FutureTask<Integer> task = new FutureTask<Integer>(c);
Thead thread = new Thread(task).start();
一般采用实现接口的方式实现,有以下有优点:
使用实现Runnable接口和Callable接口的可以继续实现其他接口或继承
在这种方式下,多个线程可以共享一个target对象(共享线程类的实例属性),所以非常适合多个相同线程处理同一份资源的情况
实现Runnable和Callable的最大区别在于Callable是调用call方法,有返回值的
2、线程的生命周期:新建、就绪、运行、阻塞、死亡
线程在以下三种方式之一结束后就会处于死亡状态
(1)run()方法执行完成,线程正常结束
(2)线程抛出一个未捕获的Exception或Error
(3)直接调用该线程的stop()方法来结束该线程——该方法很容易导致对象受破坏,通常不推荐使用
3、线程的一些方法
join():等待另一线程执行完才执行
sleep():睡眠,不会释放对该同步监视器的锁定
wait():等待直到有notify()或者notifyAll()的调用,会释放对该同步监听器的锁定
yield():暂时放弃cpu占用,变为就绪,不会释放对该同步监视器的锁定
notify():从wait()后的线程中,调度其中一个线程
notifyAll():唤醒所有wait()后的线程
suspend():将该线程挂起,不会释放对该同步监视器的锁定。直到有resume(),但是这种方式会引起死锁,应尽量避免使用
4、线程同步
(1)使用synchronized同步代码块或同步方法
(2)使用同步锁Lock
5、线程的通信
(1)传统的方式是使用上面3的方法进行通信
(2)如果使用了同步锁Lock,则不能使用wait()、notify()、notifyAll()进行线程通信,这时需要使用Condition
(3)是要哄阻塞队列控制线程的通信
6、线程池
7、Daemon Thread的特点:如果所有的前台线程都死亡,后台线程会自动死亡,然后虚拟机也退出,基于这样的特点,有些功能是不合适用守护线程来实现的
创建守护线程的过程应该注意:setDaemon(true)必须在start()方法之前调用。否则会引发IllegalThreadStateException异常
8、sleep方法和yield方法的区别:
(1)sleep方法暂停当前线程,会给其他线程执行机会,不会理会其他线程的优先级;但是yield方法只会给优先级相同或更高的线程执行的机会。所以yield完全有可能变成就绪后直接就又重新执行
(2)sleep方法声明抛出了InterruptedException异常,所以调用sleep方法要么捕捉该异常,要么显示声明抛出该异常。而yield方法则没有声明抛出任何异常
(3)sleep方法比yield方法有更加好的移植性,通常不要依靠yield来控制并发线程的执行
相关文章推荐
- Java【多线程知识总结(10)】线程通信之wait()与notify()的运用--模拟指挥官指挥2个连队交替轰炸战区<另外的写法>
- 黑马程序员 JAVA基础<三> 多线程
- 黑马程序员:Java基础总结----子接口 set<E>及其实现类
- Java总结<四>集合框架
- 排序算法终结总结<Java实现>
- Java多线程实例<转>
- <杂谈1002>HTML作为GUI前段,Java/NDK作为业务后端开发方式总结
- Linux 兴趣小组暑假学习--学习总结<三>
- bo1-About Java 多线程-------->Java多线程编程总结
- java中的移位运算符:<<,>>,>>>总结
- 【转】值得细读,40个Java多线程问题总结<一>
- 黑马程序员 Java基础<三>--->面向对象
- JAVA多线程 <三>单例模式下的多线程问题
- Java基础<七>_多线程
- EBS OAF开发中的Java 实体对象(Entity Object)<三>
- Orace数据库锁表的处理与总结<摘抄与总结三>
- Java基础<三>---> 流程控制与函数
- _Java基础<三>_Java语言基础组成(下)
- java微信网页授权获取用户信息以及JSSDK自定义分享等功能<三>
- 【吐槽篇之经验<三>】性能问题定位与调优测试总结