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态