Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不使用SecurityManager的情况下保护私有线程_Java_Multithreading_Security_Standards - Fatal编程技术网

Java 如何在不使用SecurityManager的情况下保护私有线程

Java 如何在不使用SecurityManager的情况下保护私有线程,java,multithreading,security,standards,Java,Multithreading,Security,Standards,像ThreadPoolExecutor类一样,我在类中使用private后台线程(MyClass)。 但是,一旦我启动我的线程,任何人都可以像这样调用我的线程的方法: Thread[] threads = new Thread[10]; Thread.currentThread().getThreadGroup().enumerate(threads); threads[**index of my thread**].run(); @Override public void run(){

ThreadPoolExecutor
类一样,我在类中使用
private
后台线程(
MyClass
)。
但是,一旦我启动我的线程,任何人都可以像这样调用我的线程的方法:

Thread[] threads = new Thread[10];
Thread.currentThread().getThreadGroup().enumerate(threads);
threads[**index of my thread**].run();
@Override
public void run(){
    if(.....) throw new UnsupportedOperationException("do not invoke run() directly");
}

@Override
public void setUncaughtExceptionHandler(.....){
    throw new UnsupportedOperationException("cannot change handler");
}

........
这种调用破坏了
MyClass
的结构

当然,我可以使用
SecurityManager
来避免这种情况,
但是我不能强迫
MyClass
的用户在安装了
SecurityManager
的情况下运行JVM。
所以,如果我不想破坏
MyClass
的结构,
我必须编写这样的冗长代码:

Thread[] threads = new Thread[10];
Thread.currentThread().getThreadGroup().enumerate(threads);
threads[**index of my thread**].run();
@Override
public void run(){
    if(.....) throw new UnsupportedOperationException("do not invoke run() directly");
}

@Override
public void setUncaughtExceptionHandler(.....){
    throw new UnsupportedOperationException("cannot change handler");
}

........
那么,我的问题是“谁是负责人?”
我可以假设没有人调用私有线程的方法吗?
(这种调用引起的缺陷可以忽略不计)

我必须为非法访问做好准备吗?
(在所有情况下,对象都必须是完美的)

更一般地说,
关于这类问题有(官方)的编程标准吗


谢谢。

< P>如果我是你,我会考虑以下几点:
1) 线程并不意味着可以重新运行,它应该只启动(并运行)一次。
2) 为了从
thread.currentThread().getThreadGroup().enumerate(线程)中获取线程您的线程必须已经运行。

3) 在
run()。您应该构建易于正确使用且难以错误使用的API(通过适当的文档和合理使用可见性级别,如public/protected/private)。然而,你的工作不是担心是否有人会在错误的时间故意调用错误的方法。如果他们这样做,那么他们将“使保修失效”。我不确定您是否是Java新手,但不管您使用了什么“保护”,都有各种方式可以破坏代码并将其弄乱(使用反射、反编译/修改/重新编译等)

作为旁注,SecurityManager不是为了保护代码不受用户(例如DRM及其同类)的影响,而是为了保护用户不受代码的影响。因此,它不是保护代码不被其他开发人员“误用”的有效方法

更新


反对是一个更复杂的问题。想想有人已经使用你的代码一段时间了。理想情况下,他们应该能够升级到新版本,而不修改代码(假设新版本与旧版本合理兼容)。在这种情况下,如果一个不推荐使用的方法“仍然有效”,但不再是“正确的方法”,那么您就不希望在以前的工作代码中抛出异常。但是,如果您已经给了用户很多警告,而现在这个方法不再有效,那么是的,您想抛出一个异常。也就是说,如果您正在创建一个全新的API,并且碰巧使用了一个不推荐使用的方法公开了一个类,您永远不希望您的用户使用它,那么在这种情况下抛出一个异常也是合理的。

下面是一个后续想法:如果您正在编写一个其他程序员将使用的库,然后,您不应该试图对客户机隐藏线程,而应该做相反的事情:当您想要创建一个新线程时,您应该允许客户机为您创建它

使用
ThreadFactory
实例创建新线程

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

ThreadFactory myThreadFactory = Executors.defaultThreadFactory();

public void setThreadFactory(ThreadFactory clientThreadFactory) {
    myThreadFactory = clientThreadFactory;
}

void someMethodThatMakesAThread(...) {

    Runnable r = new Runnable() {
        @Override
        public void run() {
            ...
        }
    };
    Thread t = myThreadFactory.newThread(r);
    t.start();
    ...
}
如果客户端选择调用您的
setThreadFactory()
方法,那么您的代码将使用客户端的
ThreadFactory
实例生成新线程。这使客户机能够调试程序、记录线程创建事件、控制线程优先级、在线程组中组织线程等等,。。。所有这些都使您的模块更加有用,对于希望在大型程序中使用该模块的程序员来说更具吸引力,而大型程序中除了您的模块之外还有许多其他线程


另一方面,如果您的客户端选择不调用
setThreadFactory()
,那么默认的
ThreadFactory
基本上只会为您调用
new Thread(r)

您担心的人是谁?攻击者?另一个开发人员使用你的代码?在你的机器上还是他们的?等你们是担心他们得到了敏感数据,还是担心代码不能按设计的方式工作?我很抱歉回答这个不详细的问题。在这种情况下,我担心另一个开发人员使用我的代码。MyClass中没有敏感数据。(这个类的主要功能是使用javax.sound.sampled.SourceDataLine播放声音)我的意图是使我的代码完美(在所有情况下都能按设计工作),但如果可能的话,我还想了解其他情况。(“攻击者”和“敏感”案例)作为库代码的作者,您的工作是设计API,使客户机开发人员能够轻松地按照您的预期方式使用库,并避免他们犯愚蠢的错误。但是,你不需要强迫他们按照你想要的方式使用它。谢谢你,詹姆斯·拉格。那么,你的意思是“访问后台私有线程是一个愚蠢的错误(很难发生),你不需要关心它。”?这与调用的方法无关。这是关于如何称呼他们。没有人键入
Thread.currentThread().getThreadGroup().enumerate(线程)偶然!这不是一个愚蠢的错误;以一种你不想被使用的方式使用你的库是一种蓄意的黑客行为。你不必担心这一点(请参阅@jtahlborn的答案了解原因)。谢谢。我担心
enumerate
在我的类之外被调用。当我在编辑代码时,检查
isRunning()
是有效的,因为它断言“这个线程不应该是可重新运行的”