关于java线程方面的心得

来源:互联网 发布:热血无赖怎么优化 编辑:程序博客网 时间:2024/05/19 23:55

      对于java,虽然在学校时早已认识,但确实不熟练,我只能算是一个初学者,刚入职,老大就交给了我一个关于线程的任务。起初还没什么,照着一些参考代码也能写出来可以运行的程序。但程序测试、应用一段时间后,问题也暴露出来了。关于线程出现的这些问题,真的把我弄得很迷糊,但经过一段时间上网学习、阅读有关方面书籍、搜集资料,线程的概念以及如何应用逐渐清晰起来,现在将我我最近一段时间遇到的一些问题及解决方法总结如下:

 

一、关于Thread类中的interrupt方法和stop方法

     我做的任务中需要对一个线程做超时控制,起初从字面意思以为interrupt方法可以打断或者说终止一个线程的运行,但经过试验这种想法是错误的,正如许多资料中写到的那样,interrupt只能将处于阻塞状态的线程阻塞状态打断,阻塞的状态可能是由于wait()、join()、sleep()方法引起的,也可能是I/O阻塞。也就是说interrupt可以跳过使线程处于的阻塞状态的代码,继续往下执行,但并不可以终断线程的run()方法。

    在我的代码中,线程体中的任务并不会产生阻塞,只是有可能运行时间过长,所以要进行超时控制,让超时的线程停下来。试过很多方法,没有奏效,最后用了不推荐使用的stop()方法。在几乎所有资料中都这样描述“public final void stop()  已过时。 该方法具有固有的不安全性。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。”但在我的程序中要进行超时控制的每个线程对象并不被其他的线程共享,每个线程独立运行,而且我想做的就是在超时的时候将线程kill掉,而不是将其中断,在没有想到更好的方法钱我选择用stop()。经测试没有出现异常。但不知程序以后运行会不会出现新的问题,如果有其他替代方法当然还是会用其他方法的,毕竟stop()还是有风险的。

 

二、关于线程体中异常的捕获

    在一个线程体外我们无法捕获到这个线程run方法中的异常。资料中提示说线程自己的问题自己处理,根据这条原则我将可能出异常的代码段写在另一个方法中,这个方法声明抛出可能出现的异常,然后在run()方法中调用这个方法并捕获异常,而不是在线程外捕获它。

    另外一个方法是实现UncaughtExceptionHandler接口来处理未捕获异常。但它在捕获到异常后只会跳过出异常的那一句代码,而并不会由我们控制它当出现异常时跳过某一代码块,所以有时不会得到我们想要的结果。

使用它的例子是

public static void main(String[] args) {
// 建立异常处理者
ExceptionHandler handler =new ExceptionHandler ();
//将其部署到可能出现未捕获异常的对象中

thread.setUncaughtExceptionHandler(handler);

thread.start();

}

 

class ExceptionHandler implements UncaughtExceptionHandler{
  public void uncaughtException(Thread t, Throwable e) {
      //这里是对未捕获的异常的处理操作

     fileLog.warn(e+" This thread is:" + t.getName());
  }
 }

 

三、关于线程池的应用

  网上找到的线程池应用的例子:

public class Concurrent4ThreadPool { // 用于管理线程和提供线程服务的类
 private static final Logger fileLog = Logger.getLogger("rfLogger");
    private ExecutorService exe = null;// 线程池
    private static final int POOL_SIZE = 4;// 线程池的容量
    public Concurrent4ThreadPool() {
        exe = Executors.newFixedThreadPool(POOL_SIZE);// 创建线程池
        System.out.println("the server is ready...");
    }

    public void server() {
        int i = 0;
        while (i < 20) {
            exe.execute(new ProxyThread(i));// 运行线程池
            i++;
           
        }
        exe.shutdown();
        System.out.println("shutdown over.");
    public static void main(String[] args) {
        new Concurrent4ThreadPool().server();
    }

}

   应该注意的是线程池中execute()执行的是线程对象的run()方法,而不是start()方法。如果重写了线程中的start()方法,再在线程池中调用execute()方法是不会调用自己重写的start()方法的,所以如果要通过线程池启动线程,要将线程的所有操作都在run()方法中进行。

 

  以上是我最近一段时间对线程一些问题的理解,其中定有不当与错误之处,还望大家不吝赐教,小弟感激不尽。

 

 

 

 

 

原创粉丝点击