How to access Hibernate session from src folder? - java

I would like to know how to access the Service and Domains properly in this sample class placed in src/java folder
public class NewsIngestion implements Runnable {
private String str;
private int num;
private Logger log = Logger.getLogger("grails.app");
private static boolean isRunning;
private Thread t;
private WorkerJobService jobService;
private NewsService newsService;
public NewsIngestion(String s, int n)
{
jobService = new WorkerJobService();
newsService = new NewsService();
str = s;
num = n;
isRunning = false;
t = new Thread (this, "NewsIngestion");
}
public void run ()
{
while(isRunning){
try{
if(jobService.isJobEnabled("ConsumeFeedsJob") && jobService.lockJob("ConsumeFeedsJob")){
log.info("${this.class.name}: ConsumeFeedsJob started");
try{
// get all sources
List sources = (List) InvokerHelper.invokeMethod(RSSFeed.class, "list", null);
for(int i = 0; i < sources.size(); i++) {
RSSFeed s = (RSSFeed) sources.get(i);
// check if it's time to read the source
int diff = DateTimeUtil.getSecondsDateDiff(s.getLastChecked(), new Date());
if(s.getLastChecked() == null || diff >= s.getCheckInterval()){
List keyword_list = (List) InvokerHelper.invokeMethod(Keyword.class, "list", null);
for(int j = 0; j < keyword_list.size(); j++) {
String keyword = (String) keyword_list.get(j);
try{
newsService.ingestNewsFromSources(keyword, s);
}catch(Exception e){
log.error("${this.class.name}: ${e}");
}
log.debug("Completed reading feeds for ${keyword}.");
log.info("${this.class.name}: Reading feeds for '${keyword}' (${s.feedName}) took ${Float.toString(st2.getDuration())} second(s).");
}
s.setLastChecked(new Date());
InvokerHelper.invokeMethod(RSSFeed.class, "save", null);
}
log.info("${this.class.name}: Reading feeds for '${s.feedName}' for all keywords took ${Float.toString(st.getDuration())} second(s).");
}
}catch(Exception e){
log.error("${this.class.name}: Exception: ${e}");
}
log.info("${this.class.name}: ConsumeFeedsJob ended.");
// unlock job
jobService.unlockJob("ConsumeFeedsJob");
}
log.info("alfred: success");
}
catch (Exception e){
log.info("alfred exception: " + e.getMessage());
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
log.info(e.getMessage());
}
}
}
public void start() {
if(t == null){
t = new Thread (this, "NewsIngestion");
}
if(!isRunning){
isRunning = true;
t.start();
}
}
public void stop() {
isRunning = false;
}
public boolean isRunning() {
return isRunning;
}
}
I'm encountering this error message:
No Hibernate Session bound to thread,
and configuration does not allow
creation of non-transactional one here
Thanks.

You shouldn't instantiate the service class by yourself, but instead take the class instance from the main context
import org.codehaus.groovy.grails.commons.ApplicationHolder
def ctx = ApplicationHolder.application.mainContext
def newsService = ctx.newsService
If you're using Java
import org.codehaus.groovy.grails.commons.ApplicationHolder
public class SomeClass {
SomeService someService;
public SomeClass() {
someService = (SomeService) ApplicationHolder.getApplication().getMainContext().getBean("someService");
}
}

Consider using Spring and #Transactional annotation or AOP.

Related

Spring Batch - Not Shutting down - Due to Static Method call

I have completed a spring batch (Standalone Jar) in Spring Boot + CommandLineRunner. But the JVM is not getting shutdown after completion. After doing some research initially I thought its not shutting down because of below reasons.
1 . I am not closing the spring application context at the end ofcommandline runner.
2 . Executor service is not shutdown properly which might have caused the JVM from shutting down.
I dont want to call system.exit which is a forceful shutdown.
I tried closing the application context and also verified executor service is shutdown using isShutdown method (returns true).
Then I found out the root cause, it is because I am calling a static method which is the culprit. When I commented the static method call, the job was shutting down gracefully even if I dont close the application context explicitly.
I am not sure why this behavior and do I need to convert everything to objects or is there something else I am missing here. Can someone please throw some light.
Main Class
#SpringBootApplication
#ComponentScan(basePackages = "com.acn.abp.printbatch")
#EnableTransactionManagement
#ImportResource({ "ABPBatchInfrastructure.xml", "financeBillPayAppConfig.xml" })
public class financeBillPayFileUploadApplication extends PrintBatchConstants implements CommandLineRunner {
#Autowired
private NotifyConfig notify;
#Autowired
private ApplicationContext ctx;
static final Logger logger = LoggerFactory.getLogger(financeBillPayFileUploadApplication.class);
public static void main(String[] args) {
SpringApplication application = new SpringApplication(financeBillPayFileUploadApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
#Override
public void run(String... args) throws Exception {
logger.info(notify.getEnvironment());
JobLauncher jobLauncher = ctx.getBean(JobLauncher.class);
Job job = ctx.getBean(Job.class);
jobLauncher.run(job,
new JobParametersBuilder()
.addString(batchDocumentClass, "InvoiceStatementDocumentation")
.addString(batchType, "2020-06-04")
.addString(batchEmailID, notify.getSupportEmailId())
.addString(batchEnvironment, notify.getEnvironment())
.toJobParameters());
System.out.println("Here cxf");
((ConfigurableApplicationContext)ctx).close();
}
}
Below Class which is causing the problem. If I comment out below code then everything works perfectly.
populateItemDocuments(job, printConfig.geteCMObjectStore(), printConfig.geteCMUserId());
Class file where this method is called
#Component
public class DuplexWorker implements Callable {
static final Logger logger = LoggerFactory.getLogger(DuplexWorker.class);
#Autowired
private ManageFormService formgmtClient;
#Autowired
private PostScriptService postScriptService;
#Autowired
private BarcodeService barcodeService;
private static CfBatchPrintConfiguration printConfig;
private static CfPersistenceUtil dbUtilService;
private static FilenetDocumentRetrieval docmgmtClient;
#Autowired
public DuplexWorker(CfPersistenceUtil dbUtilService,CfBatchPrintConfiguration printConfig,FilenetDocumentRetrieval docmgmtClient) {
DuplexWorker.dbUtilService = dbUtilService;
DuplexWorker.printConfig = printConfig;
DuplexWorker.docmgmtClient=docmgmtClient;
}
private MailUtil mailUtil;
private NotifyConfig notify;
private List<PrintJobItem> printJobItems;
private List<String> groupIds;
private ArrayList duplexJobs;
private String groupId;
private CountDownLatch latch;
public DuplexWorker(ArrayList duplexJobs, String groupId,CountDownLatch latch) {
super();
this.latch=latch;
this.duplexJobs = duplexJobs;
this.groupId = groupId;
}
public DuplexWorker(CountDownLatch latch, MailUtil mailUtil,NotifyConfig notify,List<PrintJobItem> findByPrintStatusEquals,List<String>groupIds) {
this.latch=latch;
this.mailUtil=mailUtil;
this.notify=notify;
this.printJobItems=findByPrintStatusEquals;
this.groupIds=groupIds;
}
#Override
public Object call() throws Exception {
try {
if ((duplexJobs != null) && (!duplexJobs.isEmpty())) {
String prevJobId = null;
int docCount = 0;
CvPrintJob consolidatedPrintJob = (CvPrintJob)duplexJobs.get(0);
ArrayList printItems = new ArrayList();
if (consolidatedPrintJob != null)
{
ArrayList items = consolidatedPrintJob.getPrintJobItems();
int numPages = 0;
if ((items != null) && (!items.isEmpty()))
{
CvPrintJobItem firstItem = (CvPrintJobItem)items.get(0);
numPages = CfBatchPrintUtil.getItemTotalPages(firstItem);
logger.info("Item Total Pages == " + numPages);
logger.info("Job Item Page Limit == " +
printConfig.getJobItemPageLimit());
consolidatedPrintJob.setSequence(firstItem.getSequence());
}
if (numPages <= printConfig.getJobItemPageLimit())
{
consolidatedPrintJob.setHasLargeItems(false);
logger.info("Item setHasLargeItems == false");
}
else
{
consolidatedPrintJob.setHasLargeItems(true);
logger.info("Item setHasLargeItems == true");
}
}
ArrayList startBannerDataList = new ArrayList();
ArrayList barcodeList = new ArrayList();
ArrayList barcodeCorresPageCount = new ArrayList();
ArrayList statementNumberList = new ArrayList();
for (int i = 0; i < duplexJobs.size(); i++)
{
CvPrintJob job = (CvPrintJob)duplexJobs.get(i);
if ((prevJobId == null) ||
(!prevJobId.equalsIgnoreCase(job.getJobId()))) {
docCount = 0;
}
populateItemDocuments(job, printConfig.geteCMObjectStore(), printConfig.geteCMUserId());
}
consolidatedPrintJob.setPrintJobItems(printItems);
}
else
{
logger.info("====================================================================");
logger.info("=================>> No DUPLEX jobs to process <<===================");
logger.info("====================================================================");
}
duplexJobs = null;
this.latch.countDown();
System.gc();
return null;
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
public static void populateItemDocuments(CvPrintJob job, String objectStore, String userid)
throws CfException
{
logger.info("Enters populateItemDocuments");
try
{
ArrayList items = job.getPrintJobItems();
job.setIsProcess(true);
ArrayList modelDocList = null;
logger.info("Items size::::::" + items.size());
for (int i = 0; i < items.size(); i++)
{
modelDocList = new ArrayList();
CvPrintJobItem x = (CvPrintJobItem)items.get(i);
ArrayList guidList = x.getGuidList();
if ((guidList != null) && (!guidList.isEmpty())) {
modelDocList.addAll(guidList);
}
logger.info("guidList size::::::" + guidList.size());
CvRenderPayloadRequest cvRenderPayloadRequest = null;
if ((modelDocList != null) && (!modelDocList.isEmpty()))
{
cvRenderPayloadRequest = new CvRenderPayloadRequest();
logger.info("Before creating CvRenderPayloadRequest");
logger.info("Document Class::: " +
x.getDocumentClass());
cvRenderPayloadRequest.setDocumentClass(
x.getDocumentClass());
cvRenderPayloadRequest.setGuid(modelDocList);
cvRenderPayloadRequest.setUserId(userid);
logger.info("After creating the CvRenderPayloadRequest");
try
{
if (cvRenderPayloadRequest != null)
{
List pdfContents = docmgmtClient.retrieveDocument(cvRenderPayloadRequest.getGuid());
if ((pdfContents != null) &&
(!pdfContents.isEmpty()))
{
logger.info(
"PDF contents sizenew::::::::::::::" + pdfContents.size());
Iterator pdfItr = pdfContents.iterator();
while (pdfItr.hasNext())
{
byte[] contents = (byte[])pdfItr.next();
CvPrintJobItem item = (CvPrintJobItem)items.get(i);
item.addDocumentList(contents);
int filenetpagecount = 100;
item.setPageCountFromFileNet(filenetpagecount);
logger.info("PageCOunt from Filenet " + filenetpagecount);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
throw new CfException(" Error populating documents" + e);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
throw new CfException(" Error populating documents" + e);
}
logger.info("Exits populateItemDocuments");
}
First of all you are using Tomcat server that runs the application. If you want to make standalone spring application you can configure like below
#Configuration
public class ApplicationMain {
#Bean
public Stackoverflow stackoverflow() {
return new Stackoverflow ();
}
public static void main(String[] args) {
ConfigurableApplicationContext configurableApplicationContext = new AnnotationConfigApplicationContext(ApplicationMain.class);
System.out.println(configurableApplicationContext.getBean("stackoverflow"));
}
}
'JVM is not getting shutdown after completion.' is normal behavior for Tomcat server because it waits for request to handle.
You can give basepackage like below
new AnnotationConfigApplicationContext("com.example");
it will scan the package for you

WorkStealingPool exits unexpectedly

I submitted some Runnables to an ExecutorService. Inside these Runnables, wait() and notify() are called. The code works with newFixedThreadPool as the ExecutorService. With newWorkStealingPool, the process exits unexpectedly without any error message.
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
// For regular expressions
import java.util.regex.Matcher;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.*;
import java.util.concurrent.*;
public class TestPipeline {
public static void main(String[] args) {
runAsThreads();
}
private static void runAsThreads() {
final BlockingQueue<String> urls = new OneItemQueue<String>();
final BlockingQueue<Webpage> pages = new OneItemQueue<Webpage>();
final BlockingQueue<Link> refPairs = new OneItemQueue<Link>();
final BlockingQueue<Link> uniqRefPairs = new OneItemQueue<Link>();
final ExecutorService executor = Executors.newWorkStealingPool(6);
// final ExecutorService executor = Executors.newFixedThreadPool(6);
executor.submit(new UrlProducer(urls));
executor.submit(new PageGetter(urls, pages));
executor.submit(new LinkScanner(pages,refPairs));
executor.submit(new Uniquifier<Link>(refPairs,uniqRefPairs));
executor.submit(new LinkPrinter(uniqRefPairs));
}
}
class UrlProducer implements Runnable {
private final BlockingQueue<String> output;
public UrlProducer(BlockingQueue<String> output) {
this.output = output;
}
public void run() {
System.out.println("in producer");
for (int i=0; i<urls.length; i++)
output.put(urls[i]);
}
private static final String[] urls =
{ "http://www.itu.dk", "http://www.di.ku.dk", "http://www.miele.de",
"http://www.microsoft.com", "http://www.cnn.com", "http://www.dr.dk",
"http://www.vg.no", "http://www.tv2.dk", "http://www.google.com",
"http://www.ing.dk", "http://www.dtu.dk", "http://www.bbc.co.uk"
};
}
class PageGetter implements Runnable {
private final BlockingQueue<String> input;
private final BlockingQueue<Webpage> output;
public PageGetter(BlockingQueue<String> input, BlockingQueue<Webpage> output) {
this.input = input;
this.output = output;
}
public void run() {
while (true) {
System.out.println("in pagegetter");
String url = input.take();
// System.out.println("PageGetter: " + url);
try {
String contents = getPage(url, 200);
output.put(new Webpage(url, contents));
} catch (IOException exn) { System.out.println(exn); }
}
}
public static String getPage(String url, int maxLines) throws IOException {
// This will close the streams after use (JLS 8 para 14.20.3):
try (BufferedReader in
= new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<maxLines; i++) {
String inputLine = in.readLine();
if (inputLine == null)
break;
else
sb.append(inputLine).append("\n");
}
return sb.toString();
}
}
}
class Uniquifier<T> implements Runnable{
private final Set<T> set = new HashSet<T>();
private final BlockingQueue<T> input;
private final BlockingQueue<T> output;
public Uniquifier(BlockingQueue<T> input, BlockingQueue<T> output){
this.input = input;
this.output = output;
}
public void run(){
while(true){
System.out.println("in uniquifier");
T item = input.take();
if(!set.contains(item)){
set.add(item);
output.put(item);
}
}
}
}
class LinkScanner implements Runnable {
private final BlockingQueue<Webpage> input;
private final BlockingQueue<Link> output;
public LinkScanner(BlockingQueue<Webpage> input,
BlockingQueue<Link> output) {
this.input = input;
this.output = output;
}
private final static Pattern urlPattern
= Pattern.compile("a href=\"(\\p{Graph}*)\"");
public void run() {
while (true) {
System.out.println("in link scanner");
Webpage page = input.take();
// System.out.println("LinkScanner: " + page.url);
// Extract links from the page's <a href="..."> anchors
Matcher urlMatcher = urlPattern.matcher(page.contents);
while (urlMatcher.find()) {
String link = urlMatcher.group(1);
output.put(new Link(page.url, link));
}
}
}
}
class LinkPrinter implements Runnable {
private final BlockingQueue<Link> input;
public LinkPrinter(BlockingQueue<Link> input) {
this.input = input;
}
public void run() {
while (true) {
System.out.println("in link printer");
Link link = input.take();
// System.out.println("LinkPrinter: " + link.from);
System.out.printf("%s links to %s%n", link.from, link.to);
}
}
}
class Webpage {
public final String url, contents;
public Webpage(String url, String contents) {
this.url = url;
this.contents = contents;
}
}
class Link {
public final String from, to;
public Link(String from, String to) {
this.from = from;
this.to = to;
}
// Override hashCode and equals so can be used in HashSet<Link>
public int hashCode() {
return (from == null ? 0 : from.hashCode()) * 37
+ (to == null ? 0 : to.hashCode());
}
public boolean equals(Object obj) {
Link that = obj instanceof Link ? (Link)obj : null;
return that != null
&& (from == null ? that.from == null : from.equals(that.from))
&& (to == null ? that.to == null : to.equals(that.to));
}
}
// Different from java.util.concurrent.BlockingQueue: Allows null
// items, and methods do not throw InterruptedException.
interface BlockingQueue<T> {
void put(T item);
T take();
}
class OneItemQueue<T> implements BlockingQueue<T> {
private T item;
private boolean full = false;
public void put(T item) {
synchronized (this) {
while (full) {
try { this.wait(); }
catch (InterruptedException exn) { }
}
full = true;
this.item = item;
this.notifyAll();
}
}
public T take() {
synchronized (this) {
while (!full) {
try { this.wait(); }
catch (InterruptedException exn) { }
}
full = false;
this.notifyAll();
return item;
}
}
}
Because the Pool is allocating threads dynamically, there are no threads alive after runAsThreads exits because that's the end of the main thread. There needs to be at least on thread running to keep the application alive. Adding a call to awaitTermination is needed. It's not needed for the fixed pool because that will always have active threads until it is explicitly shut down as noted in the JavaDocs.

Thread not starting?

Im working on a project and is confused at why the thread wont start when I call .start()
int count = 0;
while (count < urls.length) {
try {
Thread thread = new Thread(new read(urls[count]));
thread.start();
} catch (Exception e) {
}
count++;
}
but if I add
public void start() {
run();
}
in the read class and change the code to
int count = 0;
while (count < urls.length) {
try {
read thread = new read(urls[count]);
thread.start();
} catch (Exception e) {
}
count++;
}
it works fine.
EDIT : here is my read class code
its reading data from url and calling some other methods i have in the class to store data etc.
public class read implements Runnable {
URL url;
public read(String str) throws IOException {
url = new URL(str);
}
public void run() {
try {
URLConnection connect = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connect.getInputStream()));
String input;
String[] temp;
int x = 0;
while (x < 10) {
reader.readLine();
x++;
}
while ((input = reader.readLine()) != null) {
temp = input.split(" ");
temp[2].replaceAll("<br>", "");
String name = temp[0];
int flightNum = Integer.parseInt(temp[1]);
String des = temp[2];
if (Airport.containsKey(flightNum) != true) {
addFlight(flightNum, des);
addPassengerReservation(flightNum, name);
}
else {
addPassengerReservation(flightNum, name);
}
}
reader.close();
}catch (Exception e) {}
}
}
You should make a class implementing Runnable (ClassA), and override the
public void run()
method. From your "main" program, you should call:
Thread th = new Thread(new ClassA());
th.start();
You should never override the start method, or call th.run(). Calling the start method will do some "behind the scenes" work, then call your Runnable Object's run() method for you.
Thread.start() code registers the Thread with scheduler and the scheduler calls the run() method.You need to override the run() method.No need to call run() implicitly.

Thread does not run

I have some places in a excel file, each of the point have a lng and lat coordinate.
Now I try to create a static Map for each point using the google map static map api.
And I have Two component, a parser and a loader.
The Parser is used to read the excel file while the loaded is used to load tiles.
And I make the loader run in a seprate Thread.
public class Parser {
private static Parser instance;
private StaticMapLoader loader;
private Parser(StaticMapLoader loader) {
this.loader = loader;
}
public synchronized static Parser getInstance(StaticMapLoader loader) {
if (instance == null) {
instance = new Parser(loader);
}
return instance;
}
public void parse(String path) {
List<Branch> result = new ArrayList<Branch>();
InputStream inp;
try {
inp = new FileInputStream(path);
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
int rows = sheet.getLastRowNum();
for(Row r : sheet.getRows){
loader.addTask(r.type,r.name,r.x,r.y);
}
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Branch bc = new Branch("网点1", null, null);
return result;
}
}
Loader:
public class StaticMapLoader extends Thread {
private final static Logger log = Logger.getLogger(StaticMapLoader.class);
private List<Task> tasks = new ArrayList<Task>();
private String tilePath;
private boolean running = false;
public StaticMapLoader(String saveDir) {
this.tilePath = saveDir;
}
#Override
public void run() {
while (running) {
log.debug("run " + tasks.size());
if (tasks.size() > 0) {
Task t = tasks.get(0);
if (t != null && t.status == Status.waiting) {
tasks.remove(0);
t.status = Status.running;
downLoad(t);
}
}
}
}
private void downLoad(Task t) {
log.debug(String.format("load data for " + t.toString()));
//down tiles and save
t.status=Status.success;
}
public void addTask(String type, String name, double x, double y) {
log.debug(String.format("add task of :%s,%s", type, name));
tasks.add(new Task(type,name,x,y));
}
public void startRunning() {
running = true;
this.start();
}
public void stopRunning() {
running = false;
this.interrupt();
}
class Task {
Status status = Status.waiting;
String type, name;
double x,y;
Task(String type, String name, double x,double y) {
this.type = type;
this.name = name;
this.xian = xian;
this.x = x;
this.y = y;
}
}
enum Status {
waiting, running, fail, success
}
}
The process is rather simple, the StaticMapLoader have a field of ArrayList. While the Parser parse a record(place), it will be thrown to the list.
And the loader will iterator the list and download the data.
However I meet a strange problem here:
#Override
public void run() {
while (running) {
log.debug("run " + tasks.size());
if (tasks.size() > 0) {
Task t = tasks.get(0);
if (t != null && t.status == Status.waiting) {
tasks.remove(0);
t.status = Status.running;
downLoad(t);
}
}
}
}
The above codes runs, and I will get the logs like this:
run 1
add task of ..
run 2
add task of ...
However , if I comment the log line, the downLoad will be never called, I will get:
run 1
run 2
......
It seems that this may be caused by the Thread , do I miss anything?
BTW, the above codes ran inside the HttpServlet context, and I start them like this:
#Override
public void init() throws ServletException {
super.init();
try {
URL fileUrl = getServletContext().getResource(getInitParameter("xlsxFile"));
URL tilePath = getServletContext().getResource(getInitParameter("tilePath"));
StaticMapLoader loader = new StaticMapLoader(tilePath.getPath());
loader.startRunning();
Parser.getInstance(loader).parse(fileUrl.getPath());
} catch (MalformedURLException e) {
}
}

notifyAll() method is not working in my code

I am trying to implement Bully Algorithm in Java using threads.
Here is the code which I have written.
package newbully;
public class NewBully {
public static void main(String[] args) {
int total_processes = 4;
Thread1[] t = new Thread1[total_processes];
for (int i = 0; i < total_processes; i++) {
t[i] = new Thread1(new Process(i+1, i+1), total_processes);
}
try {
Election.initialElection(t);
} catch (Exception e) {
System.out.println("Possibly you are using null references in array");
}
for (int i = 0; i < total_processes; i++) {
new Thread(t[i]).start();
}
}
}
package newbully;
public class Election {
private static boolean pingFlag = false;
private static boolean electionFlag = false;
private static boolean messageFlag = false;
public static boolean isMessageFlag() {
return messageFlag;
}
public static void setMessageFlag(boolean messageFlag) {
Election.messageFlag = messageFlag;
}
public static boolean isPingFlag() {
return pingFlag;
}
public static void setPingFlag(boolean pingFlag) {
Election.pingFlag = pingFlag;
}
public static boolean isElectionFlag() {
return electionFlag;
}
public static void setElectionFlag(boolean electionFlag) {
Election.electionFlag = electionFlag;
}
public static void initialElection(Thread1[] t) {
Process temp = new Process(-1, -1);
for (int i = 0; i < t.length; i++) {
if (temp.getPriority() < t[i].getProcess().getPriority()) {
temp = t[i].getProcess();
}
}
t[temp.pid - 1].getProcess().CoOrdinatorFlag = true;
}
}
package newbully;
public class Process {
int pid;
boolean downflag,CoOrdinatorFlag;
public boolean isCoOrdinatorFlag() {
return CoOrdinatorFlag;
}
public void setCoOrdinatorFlag(boolean isCoOrdinator) {
this.CoOrdinatorFlag = isCoOrdinator;
}
int priority;
public boolean isDownflag() {
return downflag;
}
public void setDownflag(boolean downflag) {
this.downflag = downflag;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public Process() {
}
public Process(int pid, int priority) {
this.pid = pid;
this.downflag = false;
this.priority = priority;
this.CoOrdinatorFlag = false;
}
}
package newbully;
import java.util.*;
import java.io.*;
import java.net.*;
public class Thread1 implements Runnable {
private Process process;
private int total_processes;
ServerSocket[] sock;
Random r;
public Process getProcess() {
return process;
}
public void setProcess(Process process) {
this.process = process;
}
public Thread1(Process process, int total_processes) {
this.process = process;
this.total_processes = total_processes;
this.r = new Random();
this.sock = new ServerSocket[total_processes];
}
private void recovery() {
}
synchronized private void pingCoOrdinator() {
try {
if (Election.isPingFlag()) {
wait();
}
if (!Election.isElectionFlag()) {
Election.setPingFlag(true);
System.out.println("Process[" + this.process.getPid() + "]: Are you alive?");
Socket outgoing = new Socket(InetAddress.getLocalHost(), 12345);
outgoing.close();
Election.setPingFlag(false);
notifyAll();
}
} catch (Exception ex) {
//Initiate Election
System.out.println("process[" + this.process.getPid() + "]: -> Co-Ordinator is down\nInitiating Election");
Election.setElectionFlag(true);
Election.setPingFlag(false);
notifyAll();
}
}
synchronized private void executeJob() {
int temp = r.nextInt(20);
for (int i = 0; i <= temp; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Error Executing Thread:" + process.getPid());
System.out.println(e.getMessage());
}
}
}
synchronized private boolean sendMessage() {
boolean response = false;
int i = 0;
try {
if (Election.isMessageFlag()) {
wait();
}
Election.setMessageFlag(true);
for (i = this.process.getPid() + 1; i <= this.total_processes; i++) {
try {
Socket electionMessage = new Socket(InetAddress.getLocalHost(), 10000 + i);
System.out.println("Process[" + this.process.getPid() + "] -> Process[" + i + "] responded to election message successfully");
electionMessage.close();
response = true;
} catch (Exception ex) {
System.out.println("Process[" + this.process.getPid() + "] -> Process[" + i + "] did not respond to election message");
}
}
Election.setMessageFlag(false);
notifyAll();
} catch (Exception ex1) {
System.out.println(ex1.getMessage());
}
return response;
}
synchronized private void serve() {
try {
//service counter
ServerSocket s = new ServerSocket(12345);
for (int counter = 0; counter <= 10; counter++) {
Socket incoming = s.accept();
System.out.println("Process[" + this.process.getPid() + "]:Yes");
Scanner scan = new Scanner(incoming.getInputStream());
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
if (scan.hasNextLine()) {
if (scan.nextLine().equals("Who is the co-ordinator?")) {
System.out.print("Process[" + this.process.getPid() + "]:");
out.println(this.process);
}
}
if (counter == 10) {//after serving 10 requests go down
this.process.setCoOrdinatorFlag(false);
this.process.setDownflag(true);
try {
incoming.close();
s.close();
sock[this.process.getPid() - 1].close();
Thread.sleep((this.r.nextInt(10) + 1) * 50000);//going down
recovery();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
#Override
public void run() {
try {
sock[this.process.getPid() - 1] = new ServerSocket(10000 + this.process.getPid());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
while (true) {
if (process.isCoOrdinatorFlag()) {
//serve other processes
serve();
} else {
while (true) {
//Execute some task
executeJob();
//Ping the co-ordinator
pingCoOrdinator();
if (Election.isElectionFlag()) {
if (!sendMessage()) {//elect self as co-ordinator
System.out.println("New Co-Ordinator: Process[" + this.process.getPid() + "]");
this.process.setCoOrdinatorFlag(true);
Election.setElectionFlag(false);
break;
}
}
}
}
}
}
}
When I am trying to execute the code out of the 4 threads which I have created some threads are waiting premanently using wait() call. They are not being notified by notifyAll(). Can anyone suggest why this is happening?
Each thread is calling wait() on itself (on its own Thread1 instance). That means that when you call notifyAll() on that same Thread1 instance, only the single Thread1 that is waiting it will be notified, and not all the other threads.
What you have to do is make all your Thread1 objects call wait() on a single, common object, and also call notifyAll() on that same object.
Ofcourse you have to synchronize on the common object when you call wait() or notifyAll() on it; if you don't do that, you'll get an IllegalMonitorStateException.
// Object to be used as a lock; pass this to all Thread1 instances
Object lock = new Object();
// Somewhere else in your code
synchronized (lock) {
lock.wait();
}
// Where you want to notify
synchronized (lock) {
lock.notifyAll();
}
Both notify() (or notifyAll()) and wait() must be written into synchronized block on the same monitor.
For example:
synchronized(myLock) {
wait();
}
..................
synchronized(myLock) {
notifyAll();
}

Categories