Threads 线程

  • 格式:pdf
  • 大小:221.08 KB
  • 文档页数:20

Threads线程

定义、实例化、启动线程(Defining,Instantiating,andStartingThreads)阻止线程执行(PreventingThreadExecution)同步代码(SynchronizingCode)线程交互(ThreadInteraction)目录

Threads线程...............................................................................1

定义、实例化、启动线程....................................................3创建一个线程...................................................................4

定义线程...........................................................................5实例化线程.......................................................................6

启动线程...........................................................................6

启动多个线程...................................................................8线程调度.........................................................................10

阻止线程执行......................................................................11睡眠.................................................................................12

线程优先级和让权.........................................................12

Join()方法.......................................................................13同步代码..............................................................................14

同步和锁.........................................................................15线程交互..............................................................................16定义、实例化、启动线程

想象当用户启动一个拥有复杂操作的股票经纪人应用程序。一个

操作是“下载最新的股票价格”,一个操作是“检查股票价格警告”,

还有第三个业务操作是“为XYZ公司分析历史数据”。在单线程运行环境下,这些操作将是一个接一个执行。下一个操

作的发生必须是在前一个操作完成之后进行的。如果一个历史数据分析花费了半小时,随后用户选择执行下载和检查,那么那个警告可能

很晚收到,如此可能影响您的股票交易的结果。

我们使用多线程技术可以很好地解决该程序的问题。比如,我们可以把下载操作放置于一个线程中,让它在后台执行。如此,其他处

理过程可以在同一时刻执行。警告可以直接接收,分析可以用一个独立的线程执行,这样用户可以执行接下来的操作,与此同时还能获得

计算的结果。

那么线程到底是什么呢?在Java中,“Thread”意味着2个不同的意思。

●java.lang.Thread的实例●一个执行的线程

Thread的一个实例其实就是一个对象。如同Java中的其他对象

一样,它拥有变量和方法,还有堆上空间。但是一个执行的线程是一个独立拥有自己回调栈(CallStack)的过程(轻量级进程)。在Java

中,每个线程有一个回调栈。main()方法是程序的入口,称为main线程,当你查看main的回调栈,你可以发现main()是栈中的第一个方法--即在栈底。但是当你建立另一个线程后,又将出现一个新的回调栈。

创建一个线程

一个线程从java.lang.Thread的实例化开始。Thread类包含线程的创建、启动和暂停。您至少需要了解一下方法:

start()yield()

sleep()

run()run方法定义线程的所有操作。

publicvoidrun(){//您的job代码

}

您有2种方法定义线程:●继承java.lang.Thread

●实现java.lang.Runnable接口

定义线程

继承java.lang.Thread类,重写run方法:classMyThreadextendsThread{publicvoidrun(){

System.out.println("ImportantjobrunninginMyThread");

}}

如果代码修改如下:classMyThreadextendsThread{

publicvoidrun(){

System.out.println("ImportantjobrunninginMyThread");}

publicvoidrun(Strings){System.out.println("Stringinrunis"+s);

}

}重载的方法run(Strings)并非线程的入口!

实现java.lang.Runnable接口:classMyRunnableimplementsRunnable{

publicvoidrun(){

System.out.println("ImportantjobrunninginMyRunnable");}

}实例化线程

当您选择继承java.lang.Thread类,那么实例化将很方便:

MyThreadt=newMyThread();

如果是实现Runnable接口,则:MyRunnabler=newMyRunnable();

Threadt=newThread(r);当然还有一些构造方法用于构造实例化线程,但是不常用:

Thread(Runnabletarget,Stringname)

Thread(Stringname)Thread(ThreadGroupgroup,Runnabletarget)

Thread(ThreadGroupgroup,Runnabletarget,Stringname)Thread(ThreadGroupgroup,Stringname)

启动线程

通过调用线程的start方法:

如:t.start();注意调用run方法不能启动线程!

classFooRunnableimplementsRunnable{publicvoidrun(){

for(intx=1;x<6;x++){System.out.println("Runnablerunning");}

}

}publicclassTestThreads{

publicstaticvoidmain(String[]args){FooRunnabler=newFooRunnable();

Threadt=newThread(r);

t.start();//t.start();如果再次调用,将发生错误

}}

输出:

RunnablerunningRunnablerunning

RunnablerunningRunnablerunning

Runnablerunning

注意:同一线程实例只能调用一次start方法启动线程!

启动多个线程

classNameRunnableimplementsRunnable{publicvoidrun(){

for(inti=1;i<4;i++){

System.out.println("Runby"+Thread.currentThread().getName());

}}

}

publicclassManyNames{publicstaticvoidmain(String[]args){

NameRunnablenr=newNameRunnable();Threadone=newThread(nr,"Fred");

Threadtwo=newThread(nr,"Lucy");

Threadthree=newThread(nr,"Ricky");one.start();

two.start();three.start();

}

}结果可能为:

RunbyFredRunbyFred

RunbyFredRunbyLucy

RunbyLucy

RunbyLucyRunbyRicky

RunbyRickyRunbyRicky

再一次运行结果可能为:

RunbyFredRunbyFred

RunbyLucyRunbyRicky

RunbyFred

RunbyLucyRunbyLucy

RunbyRickyRunbyRicky

由此可以看出线程运行结果不可预测!

线程调度

java.lang.Thread类方法:publicstaticvoidsleep(longmillis)throwsInterruptedException当前线程睡眠millis毫秒publicstaticvoidyield()

根据优先级别决定是否让出CPU给其他线程publicfinalvoidjoin()

在当前线程结束后紧接运行publicfinalvoidsetPriority(intnewPriority)

设置线程的优先级别

java.lang.Object类方法:publicfinalvoidwait()

等待对象锁(Lock)publicfinalvoidnotify()

唤醒等待队列的某个线程

publicfinalvoidnotifyAll()唤醒等待队列的所有线程

线程状态:

线程共有5种状态:New(创建)-线程已经实例化,但是未调用start方法启动线程

Runnable(准备)-调用start方法后,线程进入此态,等待获得处理器

Running(运行)-线程运行

Waiting/blocked/sleeping(等待)-线程还活着,但是现在未运行,处于等待状态,一旦满足某些条件后,将返回Runnable态