注意这里显示的代码,我在MsgAndPack类中声明了像BufferedOutputStream这样的变量,后来在一个单独的线程中,在public void run()之后我实例化了那些相同的变量。
这是一种不好的做法,还是有这样的隐患?
我应该把这两件事都放在新创建的线程内部或外部的同一个地方吗?
public class MsgAndPack implements Runnable {
BufferedInputStream bistr;
BufferedOutputStream bostr;
FileInputStream fistr;
FileOutputStream fostr;
DataOutputStream dostr;
long length;
@Override
public void run() {
if (socket.isConnected()) {
try {
file = new File("/mnt/sdcard/JIend.db");
length = file.length();
byte[] bytes = new byte[(int) length];
fistr = new FileInputStream(file);
bistr = new BufferedInputStream(fistr);
bostr = new BufferedOutputStream(socket.getOutputStream());
dostr = new DataOutputStream(bostr);
int count;
答案 0 :(得分:3)
首先,没有像“线程那样声明变量”这样的东西。实例化和访问事项,而不是声明地点 - 没有代码只是声明。
如果要在run中实例化这些变量并仅在运行中使用它们,为什么不在运行中声明它们呢?这是最简单,最安全的解决方案。
在课程级别声明它们表明您将从多个方法访问它们。如果你不需要它,那么无论谁阅读代码都会让人感到困惑。
此外,您将它们声明为package-local,这表明此类之外的某些内容可以访问它们。这是不安全的 - 这意味着它们可以由多个线程共享,这会导致很多麻烦,因为流是有状态的而不是线程安全的。
总而言之 - 只要在一个线程中初始化并引用它们,在类级别声明这些流并不是错误的,但它非常脆弱。在一个线程中初始化并在另一个线程中访问将至少需要使它们变为易失性(另一个线程可能不会获得值更新)。所以总是尽可能使用最小的范围。
如果您的意图 在线程之间共享某些字段,请确保对它们的访问是正确同步的(同步的,易变的),或者它们本身是线程安全的。