开发者

Thread Code...anything wrong with this, must use java 1.4

I have a servlet automatically firing up when the app server starts, and in its init(), I'm making another thread:

init(){ new FooThread().start() }

in FooThread(), i want to periodically check the status of a DB value, then depending on the value, make a web service call. When these two tasks complete, I want the thread to sleep to wait a certain period then repeat. This cycle would just continue forever.

FooThread:

public class FooThread implements Runnable{
  Thread t;

  FooThread(){
    t = new Thread(this, "FooThread");
  }

 public void start(){
   t.start();
 }

  public void run() {
    try{
      while(true){
        //do the db check, then conditionally do the web services call
        logger.info("*** calling sleep() ***");
        Thread.sl开发者_如何转开发eep(50000);
        logger.info("*** now awake ***");
      }
    } catch (InterruptedException e) {
      System.out.println("*** FooThread interrupted");
    }
  }
}


Don’t start threads in your constructors because it could lead to race conditions and indeterminate behavior. Instead, call the start() method after constructing the object.

EDIT:

The reason it's bad is because you may publish the this pointer before the constructor has finished.


What you are doing is considered unsafe publication. When -this- reference escapes the constructor you have the possibility of sending a partially constructed object to thread class.

In your example what if your class and the run method looked like this:

public class FooThread implements Runnable{
  Thread t;

  private int someInt;
  private Object someObject;

  FooThread(){
    t = new Thread(this, "BBSThread");
    t.start();
    someInt = 10;
    someObject = new Object();
  }

  public void run() {
     System.out.println(this.someInt);
     System.out.println(this.someObject);     
  }
}

It is possible there that someInt prints 0 and someObject prints null. Your object is technically constructed but not completed.


You don't need to create a new variable t inside FooThread if you subclass from Thread. An instance of FooThread then already is the thread. And you don't need to call start() on it in the constructor.

A proper use of FooThread inside init() would be:

FooThread ft = new FooThread();
ft.start();                           // calls run() inside FooThread

In the code you lined out above the constructor of FooThread doesn't need any logic, run() looks fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜