- 浏览: 45063 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (43)
- JavaEE架构设计 (0)
- Java设计模式 (5)
- JTA (2)
- JDBC (0)
- Java性能研究 (4)
- SMTP协议深入研究 (0)
- 邮件送达分析 (0)
- Java线程 (2)
- MySQL性能调优 (3)
- Linux实践分析 (3)
- Spring使用总结 (1)
- ORM异常处理 (0)
- 分布式系统架构总结 (1)
- WEBSERVICE使用实例 (0)
- RMI使用记录 (0)
- Struts2使用记录 (1)
- JMS知识 (1)
- MTA-James使用总结 (0)
- Hibernate使用记录 (1)
- oracle数据库技术 (1)
- FLEX学习与应用总结 (0)
- 如何提高编码的效率 (0)
- OSGI技术学习与总结 (0)
- 公司项目osworkflow-WEB框架设计思想 (0)
- WEB前端技术应用实例 (1)
- Java工作与学习心得 (2)
- MINA框架使用 (0)
- 数据结构与算法 (6)
- 个性化推荐 (2)
- Java语言基础 (2)
- 安全与认证 (2)
- 大数据处理 (1)
- Spark (0)
最新评论
线程不是进程
作为有一定开发经验的程序员来说,在java中实现多线程是一件很容易的事情,你只需要将你的类继承Thread类或者实现Runnable接口就可以。其实线程完全可以理解为一个任务。可以同时运行多个任务的程序,就成为多线程程序。
然而线程并非进程。进程包括线程,每一个进程都拥有一套自己的变量,而线程间则共享这套变量。从而带来了很多风险,比如最典型的脏数据。这些以后会讨论。
线程状态
在java中,线程被定义成有6中状态:
NEW
至今尚未启动的线程处于这种状态。 即刚刚new出来的Thread,但是还未调用start()方法。
RUNNABLE
正在 Java 虚拟机中执行的线程处于这种状态。 该状态是调用了start()方法后的状态,出于该状态的线程不一定是正在运行的,他有线程调度器来决定是否运行。
BLOCKED
受阻塞并等待某个监视器锁的线程处于这种状态。 阻塞与等待不同,阻塞通常是得不到所需要的资源而被迫停下来等待。
WAITING
无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。
TIMED_WAITING
等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。
TERMINATED
已退出的线程处于这种状态。有两种情况会让线程退出,其一是run方法中的任务执行完成,其二是线程执行时出现异常。
java的线程状态只有如上6中,他们以enum形式被定义在Thread.State中。这里要说一下等待状态,有很多方式能够让线程进入等待状态,比如调用join()方法。
join()
对于这个方法,还是要特别的强调一下。在api中的解释如下:Blocks the current Thread (Thread.currentThread()
) until the receiver finishes its execution and dies.翻译过来就是:阻塞当前线程,然后让接受者完成任务之后,当前线程才开始继续执行任务。
但是如果接受者在被调用了join方法后,有被调用了interrupt()方法,则会抛出java.lang.InterruptedException异常。可以参考代码ThreadDemo01。
- <STRONG>package cn.edu.heut.zcl;
- public class ThreadDemo01 {
- public static void main(String[] args) {
- TA ta = new TA();
- ta.start();
- try {
- ta.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- int i = 0;
- while ((i++) < 10) {
- System.out.println("-------");
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- class TA extends Thread {
- @Override
- public void run() {
- super.run();
- int i = 0;
- while ((i++) < 40) {
- System.out.println("---->A");
- if (i == 10) {
- Thread.currentThread().interrupt();
- }
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- </STRONG>
package cn.edu.heut.zcl; public class ThreadDemo01 { public static void main(String[] args) { TA ta = new TA(); ta.start(); try { ta.join(); } catch (InterruptedException e) { e.printStackTrace(); } int i = 0; while ((i++) < 10) { System.out.println("-------"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } class TA extends Thread { @Override public void run() { super.run(); int i = 0; while ((i++) < 40) { System.out.println("---->A"); if (i == 10) { Thread.currentThread().interrupt(); } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
记住:join()方法是将当前线程阻塞
interrupt()与中断线程
开发时常常需要用到中断线程,在早期的java版本中,有stop()等方法用来控制线程生死,当时这些方法现在已经废弃,具体愿意以后会谈,同时亦可以参考sun的一片文章《Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?》网址如下:
http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
当然,jdk还是为我们提供了强化终止线程的方法。然而,interrupt方法只是可以用来请求终止线程。当对一个线程调用interrupt方法之后,线程的中断状态将被置位。每一个线程都具有一个中断状态,他是一个boolean标志。在实现自己的线程时,应该实时检查该标志,以判断线程是否被中断。
可以通过Thread.currentThread()方法得到当前线程,然后通过is isInterrupted()方法,来查看中断状态。通常如下实现:
while (!Thread.currentThread().isInterrupted() && 。。。) {}
如果你已经运行了ThreadDemo01代码,那么你会发现,在TA类中如下代码处:
if (i == 10) { Thread.currentThread().interrupt(); }
将会抛出异常java.lang.InterruptedException。这个是由于在TA线程中调用了interrupt方法后,中断状态已经置为,如果此时再调用sleep等阻塞方法后,该线程不会休眠,想法,他将抛出中断异常并且将中断状态清楚。所以如下代码是不会让线程TB停止。CopyOfThreadDemo02
- package cn.edu.heut.zcl;
- public class CopyOfThreadDemo02 {
- public static void main(String[] args) {
- TB ta = new TB();
- ta.start();
- int i = 0;
- while ((i++) < 10) {
- System.out.println("-------");
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- class TB extends Thread {
- @Override
- public void run() {
- super.run();
- int i = 0;
- while (!Thread.currentThread().isInterrupted() && (i++) < 40) {
- System.out.println("---->A");
- if(i == 4) Thread.currentThread().interrupt();//在sleep之前调用,将不能终止线程
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- //if(i == 4) Thread.currentThread().interrupt();//在sleep之后调用,将能终止线程
- }
- }
- }
package cn.edu.heut.zcl; public class CopyOfThreadDemo02 { public static void main(String[] args) { TB ta = new TB(); ta.start(); int i = 0; while ((i++) < 10) { System.out.println("-------"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } class TB extends Thread { @Override public void run() { super.run(); int i = 0; while (!Thread.currentThread().isInterrupted() && (i++) < 40) { System.out.println("---->A"); if(i == 4) Thread.currentThread().interrupt();//在sleep之前调用,将不能终止线程 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //if(i == 4) Thread.currentThread().interrupt();//在sleep之后调用,将能终止线程 } } }
你可以自己试一试,运行如上代码,不能中断TB线程。但是如果在sleep之后调用interrupt,则会中断线程。
interrupted()与isInterrupted()
这两个方法看上去很像,作用也相似可以通过下表来比较两种异同。
|
是否是static |
返回值 |
不同 |
interrupted |
是 |
当前的中断状态 |
调用后改变中断状态 |
isInterrupted |
否 |
不改变
|
线程属性----线程优先级
谈优先级可能并不陌生,在java中,每一个线程都有一个优先级。默认情况下,一个线程的优先级直接继承自他的父类。sun将java的优先级分成10级,1表示最小优先级,10表示最高优先级。同时jdk中还定义了3个常量MIN_PRIORITY(1级)、MAX_PRIORITY(10级)、NORM_PRIORITY(5级)。
线程的优先级是依赖与平台的,windows中有7个优先级。而在Linux中,java虚拟机将线程的优先级忽略,即所有线程的优先级都一样。所以在编写程序是,尽量不要依赖于优先级。
setPriority()方法,顾名思义就是设置优先级的。
yield()
yield的中文意思是:屈服。其实理解成让步更加准确。调用该方法,将导致当前执行线程出于让步状态。如果此时有其他线程一起来抢夺cpu资源,那么只要这个抢夺的线程的优先级不低于调用线程。则抢夺线程将会被调用。
线程属性----守护线程
守护线程的用途就是为其他线程提供服务。当被服务者死亡后,其也就没有存在的价值,也就跟着去死了。设置守护线程很简单:
setDaemon(true)
只需一步,轻松搞定。在使用守护线程时需要记住,永远不要去访问固有资源,如文件、数据库等。以为你不知道什么时候守护线程会结束。
可以参考DeamonDemo:
- package cn.edu.heut.zcl;
- /**
- * 演示守护线程
- * @author Legend
- *
- */
- public class DeamonDemo {
- public static void main(String[] args){
- DemonRunnable dr = new DemonRunnable();
- dr.setDaemon(true);//设置为守护线程
- dr.start();
- int i = 0 ;
- while((i++)<10){
- try {
- Thread.sleep(500);
- System.out.println(i);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- private static class DemonRunnable extends Thread{
- @Override
- public void run() {
- super.run();
- while(true){
- System.out.println("------");
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
来自:http://www.iteye.com/topic/954765
相关推荐
### C#多线程基础详解 #### 知识点一:多线程概念与优势 在C#中,多线程是指一个程序中同时执行多个线程的能力。一个线程是程序执行的基本单位,每个线程都有自己的指令指针、栈和局部变量,但共享相同的内存空间...
这个"JAVA多线程基础演练DEMO"提供了一些基础示例,帮助开发者更好地理解和掌握多线程的基本概念和用法。以下将详细讲解Java多线程的相关知识点: 1. **线程的创建** - **继承Thread类**:创建一个新类,继承自`...
通过学习和掌握这些多线程基础知识,开发者能够编写出更加高效、稳定的并发程序,提升软件系统的性能和用户体验。同时,对多线程深入理解也有助于应对面试中的技术考察,为职业生涯的晋升铺平道路。
**多线程基础** 多线程是指在一个进程中可以同时运行多个独立的执行流,每个执行流被称为一个线程。在MFC中,我们可以使用`CWinThread`类来创建和管理线程。`CWinThread`是MFC对Windows API中的`_beginthreadex`和`...
本教程将深入探讨C#中的多线程基础,包括创建线程、线程同步与通信、线程池以及线程安全等内容。 一、线程创建 在C#中,有两种主要方式来创建线程:使用`System.Threading.Thread`类和使用`System.Threading.Tasks...
在IT行业中,多线程是程序并发执行的一种方式,它极大地提高了系统资源的利用率和程序...在学习过程中,可以参考"多线程基础总结01.bmp"和"多线程基础总结01.mmap"等文件,它们可能提供了更为详细和直观的结构化知识。
本压缩包“多线程基础与基于多线程的简单聊天室”提供了对多线程技术的实践理解和二次开发的基础。以下是关于这个主题的详细知识点: 1. **多线程的概念**:多线程是指在一个程序中同时执行多个不同的线程,每个...
C#多线程是编程中的重要概念,尤其在开发高性能...总的来说,理解和掌握C#多线程基础知识对于编写高效、健壮的程序至关重要。在实际开发中,应合理利用多线程,注意线程安全,避免潜在的问题,提升软件的稳定性和性能。
以下是一些关于C#多线程的基础知识: 1. **线程的创建**:在C#中,可以使用`System.Threading.Thread`类来创建新的线程。通过实例化`Thread`类并提供一个代表新线程执行的委托,即可启动新线程。例如,`new ...
Java多线程是Java编程中的一个...以上只是Java多线程基础知识的一部分,深入学习还包括线程池的配置与优化、线程安全的设计模式、并发工具类的使用等。理解和掌握这些知识点对于编写高效、稳定的多线程程序至关重要。
### VC 线程基础知识总结 #### 一、线程概念与重要性 在计算机科学领域,线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。程序员可以通过多线程技术,实现并发执行任务,...
《新手学C#》这本书提供了一个很好的起点,帮助新手快速掌握线程基础知识。在这个压缩包文件"一看就懂线程代码"中,很可能包含了以下关键知识点: 1. **线程的创建与启动**:在C#中,可以使用`System.Threading....
Java线程基础是Java编程中的重要组成部分,尤其在多核处理器和并发编程需求日益增长的今天,理解并掌握线程的使用至关重要。IBM提供了一系列的Java线程教程,旨在帮助开发者深入理解Java线程的基本概念、创建与管理...
Java多线程基础篇讲解是针对初学者设计的教程,旨在用简洁明了的语言帮助学习者更容易理解多线程的概念和应用。多线程编程在现代计算机系统中扮演着重要角色,尤其在CPU主频发展遇到瓶颈的情况下,通过超线程技术和...
通过深入学习和实践这些Java线程基础知识,你可以有效地编写出高效、安全的多线程程序。记住,理解线程的原理和掌握同步机制是关键,这将有助于解决复杂的并发问题。阅读"Java线程.pdf"文档,你将获得更详细、全面的...
多线程从基础讲起,包括线程基础、线程属性、互斥量、共享内存、条件变量。
头歌java多线程基础 “头歌”是一个在线教育平台,提供包括Java在内的多种编程语言的在线学习资源和课程。Java多线程基础是学习Java编程中非常重要的一部分,它涉及到如何同时运行多个任务,以充分利用现代多核...
"多线程基础代码.rar"这个压缩包文件很可能是包含了一些关于多线程编程的基础示例代码,用于帮助初学者理解和实践多线程技术。 多线程允许一个应用程序同时执行多个不同的任务,每个任务被称为一个线程。在Java、C#...
Java并发编程中的线程基础是理解多线程编程的关键,它涵盖了从线程的创建到管理,再到线程间通信的全过程。多线程编程在处理高性能和高响应性的应用程序时至关重要,因为它允许程序在单个进程中同时执行多个任务,...
Java多线程基础知识 Java多线程基础知识是Java编程语言中的一项重要技术,用于提高程序的执行效率和响应速度。在这里,我们将详细介绍Java多线程基础知识的相关概念和技术。 一、程序、进程和线程 程序(Program...