线程管理

来源:互联网 发布:小鱼办公软件下载 编辑:程序博客网 时间: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) {

      // 创建一个线程组,线程数目为10State表示线程的状态

      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()方法就会被调用,并且返回当前的时间值。

 

原创粉丝点击