***********************************************声明******************************************************
原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。
由于各种原因,可能存在诸多不足,欢迎斧正!
*********************************************************************************************************
最近由于工作的原因开始决定系统学习一下Java的多线程机制。Java语言的一大特点就是内在支持多线程,这和很多语言需要通过外部开发包来实现多线程有本质区别。每个程序都有一个主线程,当程序启动时自动执行。关于多线程的一些概念性东西,见这篇博文:多线程初步。
1、Java内在支持多线程
为什么说Java内在支持多线程呢?根本原因是Java是完全面向对象的,所有Java类都有一个共同的父类-Object类。关于Object类的介绍,可以参考Java官方技术文档,在此提供一个博文链接Object类 。Object类有涉及线程同步的notify()、notifyAll()、wait()、wait(long timeOut)等函数,这些函数可以很好地唤醒或阻塞在当前对象监视器上等待线程。Java中线程有4个状态,创建状态、可运行状态、运行状态、撤消状态。
2、Java多线程的实现
要编写多线程程序,Java中必须直接或间接的使用Thread类或Runnable接口,然后重写run()方法(此方法是完成多线程各自任务的方法)。
2.1Thread类
通过继承Thread类,重写Thread的run()方法,将线程要实现的逻辑放在run()方法中实现。
1)、start方法
start()启动一个线程,当调用start方法后,系统才会开启一个新的线程来执行用户定义的子任务,在这个过程中,会为相应的线程分配需要的资源,不能多次启动一个线程。
2)、run方法
run()方法是不需用户显示调用的,当通过start方法启动一个线程之后,当线程获得了CPU执行时间,便进入run方法体去执行具体的任务。注意,继承Thread类必须重写run方法,在run方法中定义具体要执行的任务。
3)、sleep(long millis) 方法
sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。但要注意,sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。
4)、yield()方法
调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。注意,调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。
5)、stop方法
stop方法已经是一个废弃的方法,它是一个不安全的方法。因为调用stop方法会直接终止run方法的调用,并且会抛出一个ThreadDeath错误,如果线程持有某个对象锁的话,会完全释放锁,导致对象状态不一致。所以stop方法基本是不会被用到的。
2.2Runnable接口
有时类本就是属于派生类,但还需实现多线程。由于Java中不支持类的多继承,所以引入Runnable接口,Runnable只有一个未实现的run()方法,然后实例化Thread对象。具体用法参见如下代码:
public class runnable implements Runnable { private static int m_nCount = 0; @Override public void run() { // TODO Auto-generated method stub ++ m_nCount; System.out.println("m_nCount = "+m_nCount); } public static void main(String []agr) { Thread myThread1 = new Thread(new runnable()); Thread myThread2 = new Thread(new runnable()); myThread1.start(); myThread2.start(); } }
3、多线程的应用
程序关于某个数据集在处理机上的一次执行过程;而线程是进程的某个执行路径。一个进程可能有多个执行路径,每个线程仅是其中的一条。关于多线程,具体分析见这个链接:不同终端多线程区别
。
1)、如果是多台计算机分布式计算,则可通过多线程完全实现真正意义上的并行计算;
2)、如果是单台计算机,但是有多个CPU,通过多线程也可实现真正意义上的并行计算;
3)、如果是我们普通的计算机-单机单CPU单核,即使在计算的时候使用多线程我认为也是不能够实现真正意义上的并行的。
上面1)、2)决定多线程可以应用在重复任务的场合,细分任务给不同的线程;3)启发多线程可以应用于异步操作:耗时任务旁路分解,如UI计算任务用多线线程,客户端这边加个进度条显示。
4、多线程的同步问题
多线程的难点在于线程间的同步于互斥,典型的有生产者/消费者问题。关于多线程的一些同步问题,在后续会持续更新中。
由于时间有限,在写博文的过程中参考过一些文献,在此表示感谢;同时鉴于水平原因,你难免有不足之处,欢迎斧正!
原文地址:http://blog.csdn.net/xiaofengcanyuexj/article/details/40584239