线程:线程定义为一个单一的连续控制流。线程也可以称为执行环境或轻量级程序。通常一个程序被分为称作任务的小块,任务又进一步分为称作线程的更小的块。
线程包含在进程中,一个多线程的例子就IE可以同时下载文件和现实网页,多线程的主要优点是可以提高程序执行的速度。还有一个好处是一个线程可以找不停止程序其他部分的情况下暂停。Java运行时系统很多方面都依赖于线程。所有类库的设计都把多线程考虑在内。
使用线程的优点如下:
---可以更快地创建
---需要更少的开销
---交互进程可以更快地交换信息
---上下文交互更快
---利用CPU时间最优
Tread类里的线程如下:
---public thread()
构造一个新线程。该线程必须有一个run()方法和一个start()方法来激活run()方法。
---public void run()
这个方法必须被重载,应该包含线程代码。线程主体在其run()方法中执行。
---public void start()
启动线程。这将引起run()方法被调用并立即返回以便可以并发运行。
---public static void sleep(long millesecs)
当前执行线程等待(休眠)指定的时间(单位:毫秒),其他线程获得资源控制权。
---public void interrupted()
给一个线程发送中止请求。
---public static void yield()
当前线程将执行交给下一个可运行线程。
---getName()
获得一个线程名。
---getPriority()
获得一个线程优先级。
---isAlive()
确定某一个线程是否仍旧在运行。
---join()
等待某一线程终止。
---resume()
恢复执行挂起的线程,但仅在suspend()被调用之后才能使用。
---suspend()
挂起一个线程
---public final void stop()
终止一个线程。
---activeCount()
返回线程组中目前活动的线程数。
---currentThread()
返回当前执行线程对象的一个引用,是一个静态方法。
---setName(String)
设定线程名称。
---setPriority(int)
设定线程优先级。
示例一:(使用thread类创建线程)
class
mythread
extends
Thread
{
String name;
Thread t;
mythread(String s)
{
t=new Thread(this,s);
System.out.println("New thread:"+t);
t.start();
}
public void run()
{
try
{
for(int i=5;i>0;i--)
{
System.out.println(name+i);
Thread.sleep(500);
}
}
catch(InterruptedException e)
{
}
System.out.println(name+"existing...");
}
}
{
String name;
Thread t;
mythread(String s)
{
t=new Thread(this,s);
System.out.println("New thread:"+t);
t.start();
}
public void run()
{
try
{
for(int i=5;i>0;i--)
{
System.out.println(name+i);
Thread.sleep(500);
}
}
catch(InterruptedException e)
{
}
System.out.println(name+"existing...");
}
}
class
ex610
{
public static void main(String args[])
{
mythread m1=new mythread("One");
mythread m2=new mythread("Two");
System.out.println("thread m1 is alive"+m1.t.isAlive());
System.out.println("thread m2 is alive"+m2.t.isAlive());
try
{
System.out.println("waiting");
m1.t.join();
m2.t.join();
}//end try
catch(InterruptedException e)
{
}// end catch
System.out.println("thread m1 is alive"+m1.t.isAlive());
System.out.println("thread m2 is alive"+m2.t.isAlive());
System.out.println("existing main thread");
}//end main
} // end class
{
public static void main(String args[])
{
mythread m1=new mythread("One");
mythread m2=new mythread("Two");
System.out.println("thread m1 is alive"+m1.t.isAlive());
System.out.println("thread m2 is alive"+m2.t.isAlive());
try
{
System.out.println("waiting");
m1.t.join();
m2.t.join();
}//end try
catch(InterruptedException e)
{
}// end catch
System.out.println("thread m1 is alive"+m1.t.isAlive());
System.out.println("thread m2 is alive"+m2.t.isAlive());
System.out.println("existing main thread");
}//end main
} // end class
输入如下命令:
C:/think/thread>javac ex610.java
C:/think/thread>java ex610
程序输出:
New thread:Thread[One,5,main]
New thread:Thread[Two,5,main]
thread m1 is alivetrue
thread m2 is alivetrue
waiting
null5
null5
null4
null4
null3
null3
null2
null2
null1
null1
nullexisting...
nullexisting...
thread m1 is alivefalse
thread m2 is alivefalse
existing main thread
二、线程状态
如图
1、无论什么时候创建一个Thread类的实例,线程将进入 New Thread状态。下面代码说明了Thread类的实例化。
Thread nThread=new Thread(this);
这将创建一个新线程。现在没有分配资源给线程,它仅是一个空对象。因此仅可以调用start()和stop()方法。
如果试图调用Thread类的其他方法,它将抛出IllegalThreadStateException异常。
2、Runnable
一旦线程收到start()方法,它就进入Runnable(可运行)状态,但不是runing(在运行)状态。线程在Runnable阶段不能执行。由于单处理器同一时间不能执行多个线程,就需要设置线程调度的优先顺序,叫做线程优先级。
3、Not Runnable
在下列情况下线程处于Not Runnable(不可运行)状态:
---已经被挂起
---处于休眠状态
---处于等待状态
---被另一个线程锁定
可以通过调用Thread类的suspend()方法挂起一个线程,这样这个线程是不可执行的。可调用resume()执行该线程。然而suspend()不会终止线程。
当调用sleep()方法后线程开始休眠,参数以毫秒为单位传递给sleep()方法。一个休眠线程在指定时间后将进
入Runnable状态,直到那时线程才能执行。休眠线程不能使用resume()继续执行。
可以让一个线程在一个条件变量上等待,直到条件满足,即直到为真线程才可以运行。可以调用notify()方法
通知线程条件变量值。
4、Dead
线程或者自然终止,或者人为终止,run()方法里的循环结束后线程将自然终止。也可以调用stop()方法人为终止线程。使用isAlive()方法可以确定线程已开始还是已停止。
三、线程优先级
每一个线程都有一个优先级。优先级影响线程的运行顺序,较高优先级线程取代较低优先级线程。线程从创建它的线程继承优先级。可以使用线程的setPrioty()方法设置一个线程的优先级,传递给这个方法的参数是:
NORM_PRIORITY
MIN_PRIORITY
MAX_PRIORITY
当多个线程准备执行时,Java运行时系统选择一个最高优先级的线程执行。当一个线程正在执行而Java遇到一个更高优先级的线程时,Java放弃当前最新的线程而执行具有更高优先级的线程。
四、后台线程
可以把后台线程看作支持其他线程的任务的任务管理线程。在一个应用程序中它是独立的,能为同一个应用程序中的其他对象提供服务。后台线程的run()方法通常是个等待服务请求的无限循环。要指定一个线程为后台线程,可以使用布尔值参数true调用setDaemon()方法。isDaemon()方法用来检查一个线程是否是后台线程。
下例说明了后台线程的运行方式。之路不管Applet是最大化还是最小化,线程都不断地计时。
import
java.awt.Graphics;
import java.util.Date;
import java.applet. * ;
public class time extends Applet implements Runnable
{
Thread t1;
public void start()
{
if(t1==null)
{
t1=new Thread(this);
t1.start();
}//end if
}//end start
public void run()
{
while(t1!=null)
{
repaint();
try
{
t1.sleep(1000);
}//end try
catch(InterruptedException e)
{
}//end catch
}//end whlie
}//end run
public void paint(Graphics g)
{
Date d=new Date();
g.drawString(d.getHours()+":"+d.getMinutes()+":"+d.getSeconds(),5,10);
}//end paint
public void stop()
{
t1.stop();
t1=null;
}//end stop
} // end class
import java.util.Date;
import java.applet. * ;
public class time extends Applet implements Runnable
{
Thread t1;
public void start()
{
if(t1==null)
{
t1=new Thread(this);
t1.start();
}//end if
}//end start
public void run()
{
while(t1!=null)
{
repaint();
try
{
t1.sleep(1000);
}//end try
catch(InterruptedException e)
{
}//end catch
}//end whlie
}//end run
public void paint(Graphics g)
{
Date d=new Date();
g.drawString(d.getHours()+":"+d.getMinutes()+":"+d.getSeconds(),5,10);
}//end paint
public void stop()
{
t1.stop();
t1=null;
}//end stop
} // end class
//applet2.html主要代码:
< applet code ="time.class" width =200 height =100 >
</ applet >
2、选择 开始-程序-附件-命令提示符打开一个命令提示符窗口。键入cd C:/think/interfaces回车(注意cd后有个空格),再键入javac time.java回车,如果程序不出错的话,接着键入appletviewer applet2.html回车。
3、就可以看到弹出的applet小窗口。