【发布时间】:2015-10-21 00:23:50
【问题描述】:
我的事件有一个暂停机制(可运行),但我不确定在需要调用它时如何使用/调用它。
在我的课堂上,我有一个 run 方法,它将一个充满事件的数组列表提交给一个执行程序。 (参见 GreenhouseControls 上的 run())。提交事件时,Thread.sleep(eventTime);被调用,然后事件内部的 action() 被调用。
我的程序要求需要一种机制,通过一个方法(单击时将由一个方法调用)暂停所有线程,该方法稍后可以通过另一个按钮恢复。
有人知道如何实现这个机制吗?
这里是文件:
GreenhouseControls.java
package control;
/**
* In this exercise we take a different design approach to GreenhouseControls
*
* Compiled/Tested using Eclipse Version: Luna Release (4.4.0)
* TME4 Folder is located in C:\COMP 308\
*/
import java.io.*;
import java.util.regex.*;
import java.util.logging.*;
import java.util.*;
import java.util.concurrent.*;
import java.lang.reflect.*;
import tme4.*;
/**
* GreenhouseControls consists of the Greenhouse's status and methods that
* control what actions will be performed inside the Greenhouse.
* @author Ray Masiclat
*
*/
public class GreenhouseControls extends Controller implements Serializable{
/**
* status is a Set of StatusPair objects which contains information about the
* GreenhouseControls' status. The Default States are initialized in the default constructor.
*/
private Set<StatusPair> status = new HashSet<StatusPair>();
private static String file = "src/error.log";
/**
* Default Constructor - initializes each state of the Greenhouse
*
*/
public GreenhouseControls(){
status.add(new StatusPair<String, Boolean>("light", false));
status.add(new StatusPair<String, Boolean>("water", false));
status.add(new StatusPair<String, Boolean>("fans", false));
status.add(new StatusPair<String, Boolean>("windowok", true));
status.add(new StatusPair<String, Boolean>("poweron", true));
status.add(new StatusPair<String, String>("thermostat", "Day"));
status.add(new StatusPair<String, Integer>("errorcode", 0));
status = Collections.synchronizedSet(status);
}
/**
* Prints out in the console how to use the program.
*/
public static void printUsage() {
System.out.println("Correct format: ");
System.out.println(" java GreenhouseControls -f <filename>, or");
System.out.println(" java GreenhouseControls -d dump.out");
}
/**
* Takes in an errorcode and returns the appropriate Fix that will fix the
* error that occured in the past.
* @param errorcode
* @return fix
*/
public Fixable getFixable(int errorcode){
Fixable fix = null;
switch(errorcode){
case 1:
fix = new FixWindow(this);
break;
case 2:
fix = new PowerOn(this);
break;
default:
System.out.println("No Error");
break;
}
return fix;
}
/**
* shutdown - method creates a Logger that creates an error log which consists of information about the
* reason of why the program was shut down. After logging the error information, it serializes
* the current state of the program in order for it to be fixed/restored in the future.
* @throws IOException
*/
public void shutdown() throws IOException{
System.err.println("System Shutting Down");
Logger logger = Logger.getLogger("ControllerException");
FileHandler fh;
try {
fh = new FileHandler("src/error.log");
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Check for errorcode using getError method.
int checkError = this.getError();
if(checkError == 1){
logger.info("Window Malfunction");
} else if (checkError == 2){
logger.info("Power Outage");
} else {
logger.info("No Error");
}
/**
* Serialize the current state and output it onto the src/ directory as dump.out
*/
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("src/dump.out"));
out.writeObject(this);
out.writeObject(getEventList());
out.close();
System.exit(0);
}
/**
* getStatus - returns the status Set which consists of information about the current state of the program.
* @return status
*/
public Set<StatusPair> getStatus(){
return status;
}
/**
* getError - Assigns an integer which will be used when logging the error.
* The errorNum is retrieved using the status Set
* @return errorNum
*/
public int getError(){
int errorNum = 0;
//Iterate through the status Set
for(StatusPair sp : status){
//Check for the name "errorcode" and initializes errorNum from its status
if(sp.getName().equals("errorcode")){
errorNum = (int) sp.getStatus();
}
}
return errorNum;
}
/**
* getEventList - returns a List of Events in the program.
* @return eventList
*/
public List<Event> getEventList(){
return eventList;
}
/**
* Create a method in GreenhouseControls called setVariable to
* handle updating to this collection. Use the synchronization feature
* in java to ensure that two Event classes are not trying to add to
* the structure at the same time.
* s - represents the name of the status
* o - represents the status it is going to be replaced with
* @param s
* @param o
*/
public void setVariable(String s, Object o){
for(StatusPair sp : getStatus()){
if(sp.getName().equals(s))
{
sp.setStatus(o);
}
}
}
/**
* addStatus - Adds a new status in the status Set and it is used
* if the program cannot find a name in the status Set.
* @param name
* @param status
*/
public void addStatus(String name, Object status){
getStatus().add(new StatusPair<String, Object>(name,status));
}
/**
* run - creates a thread array which will be used to run Events from
* the text file. Then a for loop is created to fill up the thread
* array with Events on each index. Then the thread is started once
* an index is initialized. After an event is added in to the thread
* array it is removed from the events list.
*/
public void run(){
ExecutorService exec = Executors.newCachedThreadPool();
if(eventList.size() == 1){
exec.submit(eventList.get(0));
eventList.remove(eventList.get(0));
} else {
for(Event e : eventList){
exec.submit(e);
}
}
exec.shutdown();
/*while(eventList.size() > 0){
for(int i = 0; i < eventList.size(); i++){
exec.submit(eventList.get(i));
}
}*/
/*Thread[] threads = new Thread[eventList.size()];
while(eventList.size() > 0)
for(int i = 0; i < eventList.size(); i++){
threads[i] = new Thread(eventList.get(i));
threads[i].start();
eventList.remove(i);
}*/
}
} ///:~
Event.java
/**
* Make Event implements Runnable so that each type of event provides
* its own timing. Each event file should be a class of its own. Change
* the rest of the design to simplify this model.
*
* Assignment: TME4
* @author Ray Masiclat
* @studentid 3231308
* @date July 27, 2015
*
*
* Compiled/Tested using Eclipse Version: Luna Release (4.4.0)
* TME4 Folder is located in C:\COMP 308\
*/
package tme4;
import java.io.*;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import gui.*;
import control.*;
/**
* Event class that implements Runnable and Serializable
* @author Ray Masiclat
*
*/
public abstract class Event implements Runnable, Serializable{
/**
* eventTime - represents time it takes for the program to wait and then
* call its action method.
*/
protected long eventTime;
protected GreenhouseControls gcontrol;
protected boolean suspended = false;
/**
* Event class constructor which is used to initialize the Event's eventTime and
* GreenhouseControls object which is used for the Event to have access to its status
* variables.
* @param gc
* @param eventTime
*/
public Event(GreenhouseControls gc,long eventTime){
this.eventTime = eventTime;
this.gcontrol = gc;
}
/**
* getTime - returns the event's eventTime initialized from the constructor.
* @return eventTime
*/
public long getTime(){
return eventTime;
}
/**
* setTime - sets the eventTime
*/
public void setTime(long eventTime){
this.eventTime = eventTime;
}
/**
* run - Event class' run method is called when the Event is added in to the Thread
* and then "started". This method puts the Thread to sleep for however long the
* eventTime is. Afterwards, once it is done, it tries to run the Event's action
* method. If the action method throws an error, it is caught by the try-catch
* block which calls the GreenhouseControls object's shutdown which outputs an error.log
* file and serializes the current state of the GreenhouseControls object to a dump.out file.
*/
public void run(){
try {
synchronized(this){
while(suspended){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thread.sleep(eventTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.action();
} catch (ControllerException e) {
//Use shutdown to create error log
try {
gcontrol.shutdown();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
public void suspend(){
suspended = true;
}
public synchronized void resume(){
suspended = false;
notify();
}
/**
* abstract method used to call an Event's action method in the run method.
* @throws ControllerException
*/
public abstract void action() throws ControllerException;
} ///:~
(Pastebin: GreenhouseControls.java 和Event.java)
【问题讨论】:
-
如果您在问题中发布相关代码会更好,发布完整的代码文件有利于上下文,但当用户必须查看超过 200 行的文件时,很难获得帮助。
-
@yvesmancera 相关代码在我相信的问题中,我认为更好地了解整个班级会更容易理解。请就我的问题提出任何不清楚的问题。
标签: java multithreading concurrency threadpool executor