我们怎样才能使任何其他线程无法修改自定义线程?

时间:2014-02-21 17:39:47

标签: java multithreading

public class ThreadDemo  {
public static void main(String[] args) {
    System.setSecurityManager(new MySecurityManager());
    BThread bth=new BThread();
    AThread ath=new AThread();
     }
   }

 class AThread extends Thread {
     AThread(){


}
@Override
public void run() {
    System.out.println("This is A run() function");
    System.out.println(Thread.currentThread());

   }
  } 
class BThread extends  Thread{
 BThread(){
   System.out.println("In BThread() ");
   System.out.println(Thread.currentThread());
   System.out.println(this.getName());
   this.setName("Bth");
   this.start();
   }
@Override
     public void run() {
      System.out.println("This is B run() function");
      System.out.println(Thread.currentThread());
}

}

  class  MySecurityManager extends SecurityManager{
     public void checkAccess(Thread t) {
        super.checkAccess(t);
        if (t==Thread.currentThread()) {
        return; // thread always can modify itself
      }
     if (t instanceof AThread) {
        throw new SecurityException();
      }
   }
  }

输出:

     In BThread() 
     Thread[main,5,main]
     Thread-0
     This is B run() function
     Thread[Bth,5,main]
     Exception in thread "main" java.lang.SecurityException

1.基于阿列克谢输入,这是我尝试过的。我是否正确实施了它?

2.请解释为什么在main()中创建AThread对象时抛出异常的原因?

3.我没有修改AThread但仍然抛出异常原因?

4.我放了System.setSecurityManager(new MySecurityManager());在正确的地方

1 个答案:

答案 0 :(得分:0)

基本上,您必须声明自己的SecurityManager:

class  MySecurityManager extends SecurityManager{
  public void checkAccess(Thread t) {
    super.checkAccess(t);
    if (t.getId()==0) {// a hack to determine if we are in thread's constructor
       return; 
    }
    if (t==Thread.currentThread()) {
      return; // thread always can modify itself
    }
    if (t is non-modifiable) {
      throw new SecurityException();
    }
  }

并安装它:

System.setSecurityManager(new MySecurityManager());

现在如何确定t是否不可修改?这取决于你。可能在您的项目中已经存在一些将线程描述为不可修改的属性。如果没有,我建议您声明自己的课程NonModifiableThread extends Thread,然后检查t instanceof NonModifiableThread。另一种选择是创建特殊线程组并检查给定线程是否属于该组。

更新。

事实证明,Thread的构造函数本身调用setriority(),因此checkAccess(this)。允许另一个线程调用构造函数,以找出构造函数是否正在运行。我添加了

    if (t.getId()==0) {
       return; 
    }

到checkAccess,因为id是在构造函数的末尾分配的。但这没有记录,可以改变。更可靠的解决方案是:

  • 仅在创建所有线程后安装安全管理器,或
  • 让MySecurityManager保留所有不可修改的线程的集合,而不是检查线程的类。让NonModifiableThread的构造函数在构造函数中的安全管理器中注册自己(在超级构造函数完成之后),并在执行后取消注册NonModifiableThread.run()方法。
  • (甚至更好)在类NonModifiableThread中声明一个布尔变量,它在构造函数中被更改,以便MySecurityManager可以知道构造函数的执行是否已完成。