销毁正在运行的线程并重新初始化一个新变量

时间:2012-02-23 06:07:01

标签: java thread-safety

我正在java中创建一个远程应用程序

  1. 没有ds.close()方法的UDP服务器线程

    public class UDPThreadServer extends Thread { 
    
    private DatagramSocket datagramSocket; 
    private DatagramPacket datagramPacket; 
    private byte[] data; // the array of bytes which will store data here
    
    
    
    public UDPThreadServer() {
    
    
    
        // initialize variables
        // setup something
    }
    
    public void run() { // overriding run method
    
        while(true) { // or while(!ds.isClosed())
    
            datagramSocket.receive(dp); // receive data and assign to byte array
    
    
        }
    }
    
    }
    
  2. 主程序

    public class Main {
    
    public static UDPThreadServer udpThread; // the udp server running in thread
    
    public static void main(String[] args) {
    
    
       udpThread = new UDPThreadServer();
    
       udpThread.start(); // start the thread
    
       System.in.read();
    
    }
    
    
    }
    
  3. 假设我有这种方法

    public static void newThread() {
    
         udpThread = new UDPThreadServer(); // destroy and reinitialize thread  without calling    udpThread.stopUDP();
    
    }
    

    我对java中的线程安全感到好奇。

    调用newThread()方法???

    是否安全

3 个答案:

答案 0 :(得分:2)

这取决于你在构造函数中做了什么。您的代码无法启动新线程。

如果同时由多个线程调用安全的代码,那么它是线程安全的。

本地变量

局部变量存储在每个线程自己的堆栈中。这意味着线程之间永远不会共享局部变量。 因此它们始终是线程安全的。

本地对象引用

对象的本地引用略有不同。 引用本身不共享。但是,引用的对象不存储在每个线程的本地堆栈中。

所有对象都存储在共享堆中。如果本地创建的对象永远不会转义它创建的方法,那么它是线程安全的。

以下是线程安全本地对象的示例:

public void someMethod(){

  LocalObject localObject = new LocalObject();

  localObject.callMethod();
  method2(localObject);
}

public void method2(LocalObject localObject){
  localObject.setValue("value");
} 

对象成员(字段)

对象成员(成员变量)与对象一起存储在堆上。 因此,如果两个线程在同一对象实例上调用方法,并且此方法更新对象成员,则该方法不是线程安全的。

使用以下任何条件使字段安全

  1. 让它变得不稳定
  2. 使其成为最终(并在构造函数完成后访问它)。 more here
  3. 通过锁保护现场访问。 (使用同步或显式锁定)
  4. 使用不变性

答案 1 :(得分:1)

好像你在两个线程实例之间分享一些东西。如果是,那么您需要通过同步访问来处理对共享变量的访问。例如如果要通过多个线程使用datagramSocket读取数据,则可以设计单独的类,提供同步读取方法,该方法将从此套接字读取数据。将此类的实例传递给所有线程。现在,当方法同步时,您可以以线程安全的方式读取数据。

答案 2 :(得分:1)

udpThread = new UDPThreadServer(); // destroy and reinitialize thread  without calling    udpThread.stopUDP();

评论不正确。那行代码不会破坏任何东西;它不会'重新初始化'任何东西;并且它不会启动新线程。它只是改变变量udpThread的值,加上UDPThreadServer的构造函数可能产生的任何副作用。

  

调用newThread()方法???

是否安全

如果这就是你的意思,那肯定是线程安全的。这也没有意义。