Java 如何线程化一个复杂的模型类以提供与控制器类的同步?
如何根据复杂模型的一部分是否生成了正确的标志在控制器中继续 控制器类正在播放Midi序列队列,同时保留通过用户按钮按下动态更新的模型类实例。Midi队列结束后,控制器需要与模型同步,以检查用户在继续更新界面和移动到应用程序的下一部分之前是否已输入了一定数量的条目。该模型除了表示用户按钮按下的数组列表外,还表示了大量其他数据,因此面临的挑战是如何最好地划分同步部分 现在,我尝试的模式类似于以下模式,但由于控制器和模型之间存在嵌套类访问,因此无法工作:Java 如何线程化一个复杂的模型类以提供与控制器类的同步?,java,model-view-controller,design-patterns,concurrency,inner-classes,Java,Model View Controller,Design Patterns,Concurrency,Inner Classes,如何根据复杂模型的一部分是否生成了正确的标志在控制器中继续 控制器类正在播放Midi序列队列,同时保留通过用户按钮按下动态更新的模型类实例。Midi队列结束后,控制器需要与模型同步,以检查用户在继续更新界面和移动到应用程序的下一部分之前是否已输入了一定数量的条目。该模型除了表示用户按钮按下的数组列表外,还表示了大量其他数据,因此面临的挑战是如何最好地划分同步部分 现在,我尝试的模式类似于以下模式,但由于控制器和模型之间存在嵌套类访问,因此无法工作: //Controller ... Thread
//Controller
...
Thread entriesCoordination = new Thread( new Model.InnerClass);
entriesCoordination.start();
Thread t = new Thread (this);
t.run();
...
//in runnable nested class in controller
private Model.InncerClass c = new Model.InnerClass();
public void run() {
synchronized( c) {
while (!c.hasFinishedEntries()){
try{
c.wait();
} catch (InterruptedException ignore{}
}
}
}
//Midiqueue completed and Entries finished
}
//in Model
//in runnable nested class in Model
public synchronized boolean hasFinishedEntries() {
return fIsFinishedWithEntries;
}
public void run() {
while(true) {
try{
synchronized(this) {
try{
if(entriesArray.size() == max_size) {
fIsFinishedWithEntries = true;
notifyAll();
} else {...}
}
}
}
}
}
此外,这似乎是浪费,因为这基本上意味着我需要创建一个线程,并在用户可以选择这些按钮的整个时间内并行运行模型的内部类,而不是在知道Midi队列已结束时轮询模型
从控制器
类将同步到模型
类中的一个标志,而不必在模型中创建一个内部类来处理同步的设计模式是什么。我认为正确的做法是使用原子布尔
并在每个线程上定义方法对象以获取和设置布尔值
Model.InnerClass
将被更改为添加AtomicBoolean
,并将getter更改为不同步
private final AtomicBoolean fIsFinishedWithEntries = new AtomicBoolean();
public boolean hasFinishedEntries() {
return fIsFinishedWithEntries.get();
}
在run方法中,需要将完成的布尔值设置为true
public void run() {
while(true) {
if (entriesArray.size() == max_size) {
synchronized (this) {
fIsFinishedWithEntries.set(true);
notifyAll();
}
} else {...}
}
}
}
如果您多次执行此操作,则需要将其放置在false
的某个位置
现在,我尝试的模式类似于以下模式,但由于控制器和模型之间存在嵌套类访问,因此无法工作:
//Controller
...
Thread entriesCoordination = new Thread( new Model.InnerClass);
entriesCoordination.start();
Thread t = new Thread (this);
t.run();
...
//in runnable nested class in controller
private Model.InncerClass c = new Model.InnerClass();
public void run() {
synchronized( c) {
while (!c.hasFinishedEntries()){
try{
c.wait();
} catch (InterruptedException ignore{}
}
}
}
//Midiqueue completed and Entries finished
}
//in Model
//in runnable nested class in Model
public synchronized boolean hasFinishedEntries() {
return fIsFinishedWithEntries;
}
public void run() {
while(true) {
try{
synchronized(this) {
try{
if(entriesArray.size() == max_size) {
fIsFinishedWithEntries = true;
notifyAll();
} else {...}
}
}
}
}
}
您需要首先创建Model.InnerClass
实例,并将其注入控制器线程。将hasFinishedEntries()
设为静态是很难看的,因此您可以在控制器中调用:
private Model.InnerClass innerClass;
public ControllerThread(Model.InnerClass innerClass) {
this.innerClass = innerClass;
}
...
public void run() {
synchronized (innerClass) {
while (!innerClass.hasFinishedEntries()){
innerClass.wait();
}
}
}
如何在不同步整个模型类的情况下访问条目是否已完成
显然,只要想查看队列是否已结束,就可以轮询hasFinishedEntries()
。我不确定有没有更好的方法不用线程就可以做到这一点。是否有办法设置一个UI事件,以便经常检查某个条件?谢谢。我更新了问题,按照您的建议,在控制器中创建了Model.InnerClass
,@Gray。我并不认为我真的需要一个原子的get,set,put来表示布尔值,因为在那里控制器总是get,模型总是put,这不会给线程干扰留下任何空间,比如交错put。总的来说,您是说通过这些嵌套的“可运行”内部类来实现这一点是将同步公开给模型的某个部分,同时将其与整个模型类彻底分离的一种方法吗?您是在寻找一种方法来查看在没有同步的情况下事情是否已经完成。如果您总是要等待,那么我同意原子布尔是不必要的。嵌套的Runnable
内部类可以。由于内部对象的可见性,在内部类上同步时遇到问题。有很多方法可以解决这个问题。一种方法是将一个hasFinished()
方法放在调用内部类的外部类中。您还可以在静态最终对象lockObject=new Object()上拥有内部类锁代码>在其他类可以看到的外部类中。但是外部方法调用更干净。