我知道StackOverFlow上有很多几乎相同的答案,但它们并不适合我的需要。
给出以下代码示例:
(内心阶层)
static class OutgoingFileTransfer implements Runnable {
File sendThisFile;
outgoingFileTransfer(File sendThis) {
this.sendThisFile = sendThis;
}
@Override
public synchronized void run() {
//Send the file...
}
}
我知道,synchronized方法将锁定整个类,但只有在调用run()方法时才会这样。如果我执行以下操作:
Thread a = new Thread(new OutgoingFileTransfer(new File("c:/.../file1"))).start();
Thread b = new Thread(new OutgoingFileTransfer(new File("c:/.../file2"))).start();
可能是,Thread一个初始化file1
并且在进入synchronized方法之前,然后是Thread b中断,设置file2
并加入run()方法?这意味着,永远不会发送file1。正确?
有什么方法可以阻止这种情况吗?
我知道便宜的方法:让所有东西都是非静态的,添加boolean iAmCurrentlySendingAFilePleaseWaitInTheQueueTillTheOtherFileTransferFinished
,这样一切都顺序完成。但我认为有更好的方法可以做到这一点。谢谢你的帮助。 :)
答案 0 :(得分:2)
Thread a = new Thread(new OutgoingFileTransfer(new File("c:/.../file1"))).start();
Thread b = new Thread(new OutgoingFileTransfer(new File("c:/.../file2"))).start();
使用两个不同的OutgoingFileTransfer
对象创建两个不同的线程。每个版本都有自己的sendThisFile
版本,并对其进行操作。当多个线程同时作用于同一对象时,同步和锁定会起作用。在你的情况下,没有竞争条件的危险,两个线程是独立的并且并行运行。
<强> 编辑: 强>
Java中的静态类:
Java只允许静态内部类,而不是静态顶级类。静态类不会使其中的所有内容都是静态的。
来自Java教程:
实际上,静态嵌套类在行为上是顶级类 已经嵌套在另一个顶级类中进行打包 便利性。
因此,静态类可以像任何其他类一样实例化,可以将静态和非静态成员排成任何其他类,静态和非静态成员的行为就像任何其他类一样。
因此,在您的情况下,该类的teo独立实例有两个sendThisFile
个独立属性。在这种情况下,行为与OutgoingFileTransfer
是顶级(因此非静态)类相同。
答案 1 :(得分:1)
我认为这里的关键是对嵌套类的static
限定符的误解。
您只能将这些类声明为嵌套在其他类中的static
,这意味着
class A {
static class B {
}
}
外类永远不会是静态的(在本例中为A
)。对于类,static
意味着嵌套类不需要围绕它的外部类的实例。如果B
是静态的,则可以执行
A.B b = new A.B();
如果不是,你必须这样做:
A a = new A();
A.B b = new a.B();
这与成员和方法的static
概念严重相反。