Java中线程基本知识整理
2015-12-07 21:12
591 查看
1、什么是线程
线程是正在执行的程序的主体。每个计算机程序至少有一个线程,它就是运行应用程序本身的线程。在Java中,这个线程称为“main thread”,即主线程,它是以执行程序的main()这个方法开始的。在java中,每个程序都有一个以上的线程,这些线程可能连开发者自己也觉察不到,例如运行garbage collection和编译java bytecode成机器指令之类的线程。
2、线程的启动
继承Thread类
实现Runnable接口
应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
线程的启动有两种方式:
(1)利用Thread类的子类
(2)利用Runnable接口
3、线程的暂停
暂停线程使用sleep函数,sleep()方法用来阻塞线程一定时间,这个时间可以自己来指定。
可参看:sleep()与wait()之间的不同
4、线程共享互斥
参考:java中synchronized用法基本总结
5、线程的协调
(1)wait set
所有实例都有一个wait set,wait set是一个执行该实例的wait方法时操作停止的线程的集合。当执行wait方法时,就会进入wait set这个休息室,除非发生下面其中一种情况,否则线程会永远被留在wait set里面。
有其他线程以notify方法唤醒该线程
有其他线程以notifyAll方法唤醒该线程
其他线程以interrupt方法唤醒该线程
(2)wait方法的使用
执行上面代码,目前的线程会暂停执行,进入LOCK实例的wait set,即线程在LOCK上面wait
上面执行wait方法的线程会进入this的wait set,就变成了this上的wait。
另外,执行wait方法,线程需要首先获取锁定,当线程进入wait set时,就会释放该实例的锁定。
(3)notify方法的使用
使用notify方法就可以从wait set里面抓出一个线程将其唤醒
它会从LOCK的wait set里的线程抓出一个线程将它唤醒。被唤醒的线程就会退出wait set。另外,线程必须调用该实例的锁定,才能执行notify方法。
(4)notifyAll方法的使用
使用notifyAll方法时,会将所有在wait set里的线程都取出唤醒。
它会唤醒所有留在实例this的wait set里面的线程
对于他们的基本使用可以看看文章Object中的wait,notify,notifyAll基本使用
下面来总结一下它们的作用:
wait,notify,notifyAll都是Object类的方法,不是Thread里面的方法。
obj.wait()把现在的线程放在obj的wait set中。
obj.notify()从obj的wait set里面唤醒一个线程。
obj.notifyAll()是唤醒所有obj的wait set里面的线程。
最后放一张线程状态转移图。
参考书籍:java多线程设计模式
线程是正在执行的程序的主体。每个计算机程序至少有一个线程,它就是运行应用程序本身的线程。在Java中,这个线程称为“main thread”,即主线程,它是以执行程序的main()这个方法开始的。在java中,每个程序都有一个以上的线程,这些线程可能连开发者自己也觉察不到,例如运行garbage collection和编译java bytecode成机器指令之类的线程。
2、线程的启动
继承Thread类
实现Runnable接口
应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
线程的启动有两种方式:
(1)利用Thread类的子类
public class DemoThread extends Thread { public DemoThread() { super("DemoThread"); } public void run() { //Code } } demoThread.start();
(2)利用Runnable接口
public class DemoRunnable implements Runnable { public void run() { //Code } } new Thread(demoRunnable).start();
3、线程的暂停
暂停线程使用sleep函数,sleep()方法用来阻塞线程一定时间,这个时间可以自己来指定。
可参看:sleep()与wait()之间的不同
4、线程共享互斥
参考:java中synchronized用法基本总结
5、线程的协调
(1)wait set
所有实例都有一个wait set,wait set是一个执行该实例的wait方法时操作停止的线程的集合。当执行wait方法时,就会进入wait set这个休息室,除非发生下面其中一种情况,否则线程会永远被留在wait set里面。
有其他线程以notify方法唤醒该线程
有其他线程以notifyAll方法唤醒该线程
其他线程以interrupt方法唤醒该线程
(2)wait方法的使用
Object LOCK = new Object(); synchronized(LOCK) { LOCK.wait(); // LOCK is not held }
执行上面代码,目前的线程会暂停执行,进入LOCK实例的wait set,即线程在LOCK上面wait
synchronized(this) { wait(); }
上面执行wait方法的线程会进入this的wait set,就变成了this上的wait。
另外,执行wait方法,线程需要首先获取锁定,当线程进入wait set时,就会释放该实例的锁定。
(3)notify方法的使用
使用notify方法就可以从wait set里面抓出一个线程将其唤醒
synchronized(LOCK) { LOCK.notify(); }
它会从LOCK的wait set里的线程抓出一个线程将它唤醒。被唤醒的线程就会退出wait set。另外,线程必须调用该实例的锁定,才能执行notify方法。
(4)notifyAll方法的使用
使用notifyAll方法时,会将所有在wait set里的线程都取出唤醒。
synchronized(LOCK) { LOCK.notifyAll(); }
它会唤醒所有留在实例this的wait set里面的线程
对于他们的基本使用可以看看文章Object中的wait,notify,notifyAll基本使用
下面来总结一下它们的作用:
wait,notify,notifyAll都是Object类的方法,不是Thread里面的方法。
obj.wait()把现在的线程放在obj的wait set中。
obj.notify()从obj的wait set里面唤醒一个线程。
obj.notifyAll()是唤醒所有obj的wait set里面的线程。
最后放一张线程状态转移图。
参考书籍:java多线程设计模式
相关文章推荐
- N后问题 Java版
- Spring 组cxf宣布webservice
- Source folder is not a Java project
- java 反射机制
- 20151207 spring概要
- java中抽象类与接口的异同
- Java 理论与实践: 正确使用 Volatile 变量
- 性能分析工具之-- Eclipse Memory Analyzer tool(MAT)(一)
- Java&Xml教程(一)简介
- Java&Xml教程(一)简介
- Java&Xml教程(一)简介
- JAVA设计模式之单例模式
- Java 程序性能优化《第一章》Java性能调优概述 1.4小结
- 对内存溢出查看heapdump文件
- springmvc配置shiro进行权限控制
- java 回调函数很好懂
- java中volatile关键字的含义
- Java 程序性能优化《第一章》Java性能调优概述 1.3基本调优策略和手段
- java编码与乱码汇总
- Spring MVC事务配置