版權申明,獲得授權轉載必須保留以下申明和鏈接:
作者的blog:(http://blog.matrix.org.cn/page/kaizen)
在论坛上面常常看到初学者对线程的无可奈何,所以总结出了下面一篇文章,希望对一些正在学习使用java线程的初学者有所帮助。
首先要理解线程首先需要了解一些基本的东西,我们现在所使用的大多数操作系统都属于多任务,分时操作系统。正是由于这种操作系统的出现才有了多线程这个概念。我们使用的windows,linux就属于此列。什么是分时操作系统呢,通俗一点与就是可以同一时间执行多个程序的操作系统,在自己的电脑上面,你是不是一边听歌,一边聊天还一边看网页呢?但实际上,并不上cpu在同时执行这些程序,cpu只是将时间切割为时间片,然后将时间片分配给这些程序,获得时间片的程序开始执行,不等执行完毕,下个程序又获得时间片开始执行,这样多个程序轮流执行一段时间,由于现在cpu的高速计算能力,给人的感觉就像是多个程序在同时执行一样。
一般可以在同一时间内执行多个程序的操作系统都有进程的概念.一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间,一组系统资源.在进程概念中,每一个进程的内部数据和状态都是完全独立的.因此可以想像创建并执行一个进程的系统开像是比较大的,所以线程出现了。在java中,程序通过流控制来执行程序流,程序中单个顺序的流控制称为线程,多线程则指的是在单个程序中可以同时运行多个不同的线程,执行不同的任务.多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行.(你可以将前面一句话的程序换成进程,进程是程序的一次执行过程,是系统运行程序的基本单位)
线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程是共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈.所以系统在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多,正因如此,线程也被称为轻负荷进程(light-weight process).一个进程中可以包含多个线程.
多任务是指在一个系统中可以同时运行多个程序,即有多个独立运行的任务,每个任务对应一个进程,同进程一样,一个线程也有从创建,运行到消亡的过程,称为线程的生命周期.用线程的状态(state)表明线程处在生命周期的哪个阶段.线程有创建,可运行,运行中,阻塞,死亡五中状态.通过线程的控制与调度可使线程在这几种状态间转化每个程序至少自动拥有一个线程,称为主线程.当程序加载到内存时,启动主线程.
[线程的运行机制以及调度模型]
java中多线程就是一个类或一个程序执行或管理多个线程执行任务的能力,每个线程可以独立于其他线程而独立运行,当然也可以和其他线程协同运行,一个类控制着它的所有线程,可以决定哪个线程得到优先级,哪个线程可以访问其他类的资源,哪个线程开始执行,哪个保持休眠状态。
下面是线程的机制图:
线程的状态表示线程正在进行的活动以及在此时间段内所能完成的任务.线程有创建,可运行,运行中,阻塞,死亡五中状态.一个具有生命的线程,总是处于这五种状态之一:
1.创建状态
使用new运算符创建一个线程后,该线程仅仅是一个空对象,系统没有分配资源,称该线程处于创建状态(new thread)
2.可运行状态
使用start()方法启动一个线程后,系统为该线程分配了除cpu外的所需资源,使该线程处于可运行状态(runnable)
3.运行中状态
java运行系统通过调度选中一个runnable的线程,使其占有cpu并转为运行中状态(running).此时,系统真正执行线程的run()方法.
4.阻塞状态
一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态(blocked)
5.死亡状态
线程结束后是死亡状态(dead)
同一时刻如果有多个线程处于可运行状态,则他们需要排队等待cpu资源.此时每个线程自动获得一个线程的优先级(priority),优先级的高低反映线程的重要或紧急程度.可运行状态的线程按优先级排队,线程调度依据优先级基础上的"先到先服务"原则.
线程调度管理器负责线程排队和cpu在线程间的分配,并由线程调度算法进行调度.当线程调度管理器选种某个线程时,该线程获得cpu资源而进入运行状态.
线程调度是先占式调度,即如果在当前线程执行过程中一个更高优先级的线程进入可运行状态,则这个线程立即被调度执行.先占式调度分为:独占式和分时方式.
独占方式下,当前执行线程将一直执行下去,直 到执行完毕或由于某种原因主动放弃cpu,或cpu被一个更高优先级的线程抢占
分时方式下,当前运行线程获得一个时间片,时间到时,即使没有执行完也要让出cpu,进入可运行状态,等待下一个时间片的调度.系统选中其他可运行状态的线程执行
分时方式的系统使每个线程工作若干步,实现多线程同时运行
另外请注意下面的线程调度规则(如果有不理解,不急,往下看):
①如果两个或是两个以上的线程都修改一个对象,那么把执行修改的方法定义为被同步的(synchronized),如果对象更新影响到只读方法,那么只度方法也应该定义为同步的
②如果一个线程必须等待一个对象状态发生变化,那么它应该在对象内部等待,而不是在外部等待,它可以调用一个被同步的方法,并让这个方法调用wait()
③每当一个方法改变某个对象的状态的时候,它应该调用notifyall()方法,这给等待队列的线程提供机会来看一看执行环境是否已发生改变
④记住wait(),notify(),notifyall()方法属于object类,而不是thread类,仔细检查看是否每次执行wait()方法都有相应的notify()或notifyall()方法,且它们作用与相同的对象 在java中每个类都有一个主线程,要执行一个程序,那么这个类当中一定要有main方法,这个man方法也就是java class中的主线程。你可以自己创建线程,有两种方法,一是继承thread类,或是实现runnable接口。一般情况下,最好避免继承,因为java中是单根继承,如果你选用继承,那么你的类就失去了弹性,当然也不能全然否定继承thread,该方法编写简单,可以直接操作线程,适用于单重继承情况。至于选用那一种,具体情况具体分析。
eg.继承thread
public class mythread_1 extends thread
{
public void run()
{
//some code
}
}
public class mythread_2 implements runnable
{
public void run()
{
//some code
}
}
new mythread_1().start()
new thread(new mythread_2()).start()
public class mythread implements runnable
{
public void run()
{
system.out.println("my name is "+thread.currentthread().getname());
}
public static void main(string[] args)
{
new thread(new mythread()).start();
}
}
new thread(new mythread()).start();
new thread(new mythread()).start();
new thread(new mythread()).start();
public class mythread implements runnable
{
public void run()
{
system.out.println("my name is "+thread.currentthread().getname());
}
public static void main(string[] args)
{
thread t1=new thread(new mythread());
thread t2=new thread(new mythread());
thread t3=new thread(new mythread());
t2.setpriority(thread.max_priority);//赋予最高优先级
t1.start();
t2.start();
t3.start();
}
}
public class mythread implements runnable
{
public void run()
{
try
{
int sleeptime=(int)(math.random()*100);//产生随机数字,
thread.currentthread().sleep(sleeptime);//让其休眠一定时间,时间又上面sleeptime决定
//public static void sleep(long millis)throw interruptedexception (api)
system.out.println(thread.currentthread().getname()+" 睡了 "+sleeptime);
}catch(interruptedexception ie)//由于线程在休眠可能被中断,所以调用sleep方法的时候需要捕捉异常
{
ie.printstacktrace();
}
}
public static void main(string[] args)
{
thread t1=new thread(new mythread());
thread t2=new thread(new mythread());
thread t3=new thread(new mythread());
t1.start();
t2.start();
t3.start();
}
}
public static void main(string[] args)
{
/***************************************
threadgroup(string name)
threadgroup(threadgroup parent, string name)
***********************************/
threadgroup group1=new threadgroup("group1");
threadgroup group2=new threadgroup(group1,"group2");
thread t1=new thread(group2,new mythread());
thread t2=new thread(group2,new mythread());
thread t3=new thread(group2,new mythread());
t1.start();
t2.start();
t3.start();
}
class blanksaving //储蓄账户
{
private static int money=10000;
public void add(int i)
{
money=money+i;
system.out.println("husband 向银行存入了 [¥"+i+"]");
}
public void get(int i)
{
money=money-i;
system.out.println("wife 向银行取走了 [¥"+i+"]");
if(money<0)
system.out.println("余额不足!");
}
public int showmoney()
{
return money;
}
}
class operater implements runnable
{
string name;
blanksaving bs;
public operater(blanksaving b,string s)
{
name=s;
bs=b;
}
public static void oper(string name,blanksaving bs)
{
if(name.equals("husband"))
{
try
{
for(int i=0;i<10;i++)
{
thread.currentthread().sleep((int)(math.random()*300));
bs.add(1000);
}
}catch(interruptedexception e){}
}else
{
try
{
for(int i=0;i<10;i++)
{
thread.currentthread().sleep((int)(math.random()*300));
bs.get(1000);
}
}catch(interruptedexception e){}
}
}
public void run()
{
oper(name,bs);
}
}
public class banktest
{
public static void main(string[] args)throws interruptedexception
{
blanksaving bs=new blanksaving();
operater o1=new operater(bs,"husband");
operater o2=new operater(bs,"wife");
thread t1=new thread(o1);
thread t2=new thread(o2);
t1.start();
t2.start();
thread.currentthread().sleep(500);
}
}
class mythread_1 extends thread
{
object lock;
public mythread_1(object o)
{
lock=o;
}
public void run()
{
try
{
synchronized(lock)
{
system.out.println("enter thread_1 and wait");
lock.wait();
system.out.println("be notified");
}
}catch(interruptedexception e){}
}
}
class mythread_2 extends thread
{
object lock;
public mythread_2(object o)
{
lock=o;
}
public void run()
{
synchronized(lock)
{
system.out.println("enter thread_2 and notify");
lock.notify();
}
}
}
public class mythread
{
public static void main(string[] args)
{
int[] in=new int[0];//notice
mythread_1 t1=new mythread_1(in);
mythread_2 t2=new mythread_2(in);
t1.start();
t2.start();
}
}
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器