线程管理
来源:互联网 发布:小鱼办公软件下载 编辑:程序博客网 时间:2024/05/16 23:39
线程管理
1、 线程的创建和运行
a) 线程的创建有两种方法,继承Thread类或者事项Runnable接口
示例:
package lwl;
/*
* 创建线程类实现接口Runnable
*/
public classCreateThread implements Runnable {
private static final int SIZE = 10;
private int number;
public CreateThread(intnumber) {
this.number =number;
}
/**
* 实现Runnable接口里的run方法
*/
@Override
public void run() {
for (inti = 0; i < SIZE; i++) {
System.out.println(Thread.currentThread().getName()+
" : " + number + " * " + i + " = " + i * number);
}
}
}
主程序:
package lwl;
public classMain {
private static final int SIZE = 10;
public static void main(String[] args) {
for (inti = 0; i < SIZE; i++) {
CreateThreadcreateThread=newCreateThread(i);
//创建thread对象,这个对象时createThread
Threadthread= newThread(createThread);
//启动线程
thread.start();
}
}
}
2、 线程信息的获取和设置
a) Thread类有一些保存信息的属性,这些属性可以用来标示线程,显示线程的状态或者控制线程的优先级
b) 线程有6中状态:new 、runnable、blocked、waiting、time waiting或terminated
示例:
package lwl;
/*
* 创建线程类实现接口Runnable
*/
public classCreateThread implements Runnable {
private static final int SIZE = 10;
private int number;
public CreateThread(intnumber) {
this.number =number;
}
/**
* 实现Runnable接口里的run方法
*/
@Override
public void run() {
for (inti = 0; i < SIZE; i++) {
System.out.println(Thread.currentThread().getName()+
" : " + number + " * " + i + " = " + i * number);
}
}
}
package lwl;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.Thread.State;
public classMain {
private static final int SIZE = 10;
public static void main(String[] args) {
// 创建一个线程组,线程数目为10,State表示线程的状态
Threadthreads[]= newThread[SIZE];
Thread.Statestatus[]= newThread.State[10];
// 设置线程的优先级
for (inti = 0; i < SIZE; i++) {
threads[i] =new Thread(new CreateThread(i));
if ((i % 2) == 0) {
threads[i].setPriority(Thread.MAX_PRIORITY);
}else{
threads[i].setPriority(Thread.MIN_PRIORITY);
}
threads[i].setName("Thread"+i);
}
// 把线程状态写入到log.txt文件
try {
FileWriterfile= newFileWriter("..\\data\\log.txt");
PrintWriterpw = new PrintWriter(file);
for (inti = 0; i < SIZE; i++) {
pw.println("Main : Status of Thread " +i + " : " +threads[i].getState());
status[i] =threads[i].getState();
}
booleanfinish = false;
while (!finish) {
for (inti = 0; i < SIZE; i++) {
if (threads[i].getState() !=status[i]) {
writerThreadInfo(pw,threads[i],status[i]);
status[i] =threads[i].getState();
}
}
finish = true;
for (inti = 0; i < SIZE; i++) {
finish = finish && (threads[i].getState() == State.TERMINATED);
}
}
}catch(Exceptione) {
// TODO: handle exception
}
// 开始执行线程
for (inti = 0; i < SIZE; i++) {
threads[i].start();
}
}
private static voidwriterThreadInfo(PrintWriterpw, Thread thread,Statestate){
pw.println("Main : Id "+thread.getId()+" - "+ thread.getName());
pw.println("Main : Priority "+thread.getPriority());
pw.println("Main : Old State: "+state);
pw.println("Main : New State "+thread.getState());
pw.println("Main : **************************************");
}
}
3、 线程的中断
a) Java提供中断机制,可以使用它来结束一个线程。这种机制需要检查线程是否被中断,然后决定是否响应这个中断请求,线程允许中断请求并继续执行
示例:
package lwl;
public classPrimeGenerator extends Thread{
@Override
public void run(){
long number =1L;
while(true){
if(isPrime(number)){
System.out.println(number +" is Prime");
}
//isInterrupte()检查线程是否被中断,如果isInterrupted()返回值为true,就写一个信息并且结束线程的执行 if(isInterrupted()){
System.out.println("The Prime Generator has been Interrupted");
return;
}
number ++;
}
}
//如果number是一个质数,那么返回值为true,否则返回值为false
private boolean isPrime(longnumber) {
if(number <= 2){
return true;
}
for(longi = 2; i < number; i++){
if((number %i) == 2){
return false;
}
}
return true;
}
}
package lwl;
public classMain1 {
public static void main(String[] args) {
//创建PrimeGenerator类的一个对象,并且执行运行这个线程对象
Threadthread= newPrimeGenerator();
thread.start();
try {
Thread.sleep(5000);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//中断这个线程对象
thread.interrupt();
}
}
Thread类有一个表明线程被中断与否的属性,它存放的就布尔值。线程的interrupt()方法被调用时,这个属性就会被设置为true,isInterrupter()方法只是这个属性的值。
Thread类的静态方法interrupt()也可以来检查当前执行的线程是否被中断。
isInterrupted()和interrupted()方法有个很大的区别,isInterrupted()不能改变interrupted属性的值,但是后者能设置interrupted的值为false。应为interrupted()时一个静态方法,更推荐使用isInterrupted()方法。
4、 线程中断控制
a) 使用Java异常InterruptedException()来控制控制。
示例:
package lwl;
import java.io.File;
public classFileSearch implementsRunnable {
private StringinitPath;
private StringfileName;
public FileSearch(StringinitPath, String fileName) {
this.initPath =initPath;
this.fileName =fileName;
}
// 实现run()方法,查找文件名
@Override
public void run() {
Filefile= newFile(initPath);
// file.isDirectory()如果返回值为true这表示这个initPath时一个目录
if (file.isDirectory()) {
try {
directoryProcess(file);
}catch(InterruptedExceptione) {
System.out.println(Thread.currentThread().getName()+" : The search has been interrupted.");
}
}
}
private void directoryProcess(File file)throws InterruptedException {
Filelist[]= file.listFiles();
if (list !=null) {
for (inti = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
directoryProcess(list[i]);
}else{
fileProcess(list[i]);
}
}
}
// 检查这个方法是否被中断,如果被中断就抛出InterruptedException()异常
if (Thread.interrupted()){
throw new InterruptedException();
}
}
// 比对当前文件的文件名和要查找的文件是否匹配,如果匹配就打印到控制台,做完比较后,检查线程是否被中断,
// 如果时将抛出InterruptedException异常
private void fileProcess(File file) throws InterruptedException {
if (file.getName().equals(fileName)) {
System.out.println(Thread.currentThread().getName()+" : "+ file.getAbsolutePath());
}
// 检查这个方法是否被中断,如果被中断就抛出InterruptedException()异常
if (Thread.interrupted()){
throw new InterruptedException();
}
}
}
package lwl;
import java.util.concurrent.TimeUnit;
public classMain2 {
public static void main(String[] args) {
FileSearchfileSearch= newFileSearch("C:\\","log_network.txt");
Threadthread= newThread(fileSearch);
thread.start();
try {
TimeUnit.SECONDS.sleep(10);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thread.interrupt();
}
}
5、 线程的休眠和恢复
a) 使用sleep()方法控制线程休眠
示例:
package lwl;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import javax.print.attribute.Size2DSyntax;
public classFileClock implements Runnable{
private static final int SIZE = 10;
@Override
public void run() {
for (inti = 0; i < SIZE; i++) {
System.out.println(new Date());
try {
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedExceptione) {
System.out.println("The FileClock has been Interrupted");
}
}
}
}
package lwl;
import java.util.concurrent.TimeUnit;
public classMain3 {
public static void main(String[] args) {
Threadthread= newThread(newFileClock());
thread.start();
try {
TimeUnit.SECONDS.sleep(5);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//中断线程
thread.interrupt();
}
}
6、 等待线程的终止
a) Java中使用Thread类里的join()方法实现线程终止。当一个线程对象的join()方法被调用时,,调用它的线程将被挂起,直到这个线程对象完成它的任务。
示例:
package lwl;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public classDataSourceLoader implements Runnable {
@Override
public void run() {
System.out.println("Beggining data Source loading: " +newDate());
try {
TimeUnit.SECONDS.sleep(5);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Data source loading has finished: " +newDate());
}
}
package lwl;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public classNewworkConnectionsLoader implements Runnable {
@Override
public void run() {
System.out.println("Beggining data Source loading: " +newDate());
try {
TimeUnit.SECONDS.sleep(5);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Data source loading has finished: " +newDate());
}
}
package lwl;
import java.util.Date;
public classMain4 {
public static void main(String[] args) {
DataSourceLoaderdataSourceLoader=newDataSourceLoader();
Threadthread1= newThread(dataSourceLoader,"DataSourceLoader");
NewworkConnectionsLoadernewworkConnectionsLoader =newNewworkConnectionsLoader();
Threadthread2 =newThread(newworkConnectionsLoader,"NewworkConnectionsLoader");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Main :Configuration has been loaded: "+newDate());
}
}
如果不加等待线程join()方法,则会打印主函数里的信息
也可以给join加上时间的控制:例如thread1.join(5000)
7、 守护线程的创建和运行
a) Java有一种特殊的线程叫守护线程。这种线程优先级比较低,通常来说,当同一个应用程序里没有其他线程运行的时候,守护线程才运行。当守护线程时程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个线程
示例:
package lwl;
import java.util.concurrent.TimeUnit;
public classSetDaemonThread implements Runnable {
@Override
public void run() {
// 一直循环
for (inti = 0;; i++) {
try {
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package lwl;
import java.io.IOException;
public classMain5 {
public static void main(String[] args) {
SetDaemonThreadsetTest= newSetDaemonThread();
Threadthread= newThread(setTest);
//设置为守护线程
thread.setDaemon(true);//如果设置成false则是个死循环,没有退出条件,设置为true,即可主线程结束,
thread.start();
System.out.println("isDaemon = "+thread.isDaemon());
try {
System.in.read();
}catch(IOExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
8、 线程局部变量的使用
a) 共享数据是并发程序最核心的问题之一,对于继承Thread类或者实现Runnable接口对象来说尤其重要
b) Java提供一个线程局部变量来控制线程变量的值
示例:
package lwl;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public classUnsafeTask implementsRunnable {
// 使用ThreadLocal类控制线程中变量
private static ThreadLocal<Date>startDate=newThreadLocal<Date>() {
protected DateinitialValue() {
return new Date();
}
};
@Override
public void run() {
System.out.println("Starting Thread: "+ Thread.currentThread().getId() +startDate.get());
try {
TimeUnit.SECONDS.sleep((int) Math.rint(Math.random()* 10));
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread Finished: "+ Thread.currentThread().getId() +startDate.get());
}
}
package lwl;
import java.util.concurrent.TimeUnit;
public classMain6 {
public static void main(String[] args) {
UnsafeTaskunsafeTask= newUnsafeTask();
for (inti = 0; i < 10;i++) {
Threadthread= newThread(unsafeTask);
thread.start();
try {
TimeUnit.SECONDS.sleep(2);
}catch(InterruptedExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
线程局部变量分别为每个线程存储了各自的属性值,并提供给每个线程使用。你可以使用get()方法读取这个值,并用set()方法设置这个值。如果线程是第一次访问线程局部变量,线程局部变量可能还没有为它存储值,这个时候initialValue()方法就会被调用,并且返回当前的时间值。
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 线程管理
- 管理线程的线程池
- 管理线程之创建线程
- 管理线程之创建线程
- 【高级线程管理】线程池
- java线程状态管理
- Linux 进程管理--------------------线程
- Win2Linux 线程管理映射
- ACE_Thread_Manager线程管理学习
- 【CodeM编程】音乐研究
- 如何在JSP页面实现Word文件的预览
- IdentifierLoadAccess and Session.byId()
- [LeetCode]624. Maximum Distance in Arrays
- **图灵杯 J** 简单的变位词
- 线程管理
- SDUT-1216 杨辉三角
- 【CodeM编程】锦标赛
- 常用API
- c++ builder 中的 XMLDocument 类详解(12) -关于 XML 属性
- Codeforces Round #419 (Div. 2) C.Karen and Game 思维
- JVM内存区域分区及OOM分析
- c++ builder 中的 XMLDocument 类详解(13)
- Hibernate中Session的几个方法