I am programing a midi maker that you can make a song through the console (and later a window) but I'm having a thread issue. When I want the song to start, the thread starts but it doesn't run the function that has the song player. I copy and pasted the base code from a working project and I cant figure out why it is not running. IT prints "setting up" but not "running". Here is my code for the function:
public void songStart() throws InterruptedException {
int temp;
channelVolume = new int[channelNotes.length][channelNotes[0].length];
if (channelNotes.length < userChannels.length) {
temp = channelNotes.length;
} else {
temp = userChannels.length;
}
for (int j = 0; j < userChannelNotesNumLongest; j++) {
for (int i = 0; i < temp; i++) {
if (channelNotes[i][j] == r) {
channelVolume[i][j] = 0;
} else if (advanced == false){
channelVolume[i][j]=50;
}
}
}
System.out.println("running");
for (int i = 0; i < temp; i++) {
for (int j = 0; j < userChannelNotesNumLongest; j++) {
noteOn(userChannels[i],channelNotes[i][j],channelVolume[i][j]);
Thread.sleep(interval);
noteOff(userChannels[i],channelNotes[i][j]);
}
}
}
And this is the code for the thread:
public class SongThread extends Thread {
public void run(){
try {
Main.song.songStart();
} catch (InterruptedException e) { }
}
}
Here is were the code runs the thread (i have a print in there that does print)
if (userInput.equals("start")) {
System.out.println("setting up");
SongThread thread = new SongThread();
thread.start();
}
Note: everything works fine until the thread tries to run the function, then it just stops running it. Also, it is the same base code in the other project that works fine. The function that is displayed is in a class instance in Main called song. And I don't get an error from the catch. Keep in mind that I copy and pasted the code from a working project and the only thing different is that it is not static and runs the instance from the Main class
I have tried making the songStart function static with everything inside as well. I have used all the combinations of try / catch an d throws exceptions in the thread and the function (where the thread didn't have a try / catch or throws and where the function has a try / catch or a throws). the way I have it in my working project is a throws in the function and a try / catch in the thread.
Related
I'm currently writing a program and I have this problem where I want to move the console's cursor to a specific location on the screen.
I quickly found out that this isn't possible in java so I wrote a C# script that would do this for me, but I only can run program in a separate process.
Is there a way to solve this?
Also I'm trying not to use any extra libraries like jline.
Here are some code snippets:
C#
using System;
namespace setCursor
{
public class program
{
static void Main(string[] args)
{
int x = Convert.ToInt16(args[0]);
int y = Convert.ToInt16(args[1]);
Console.SetCursorPosition(x ,y);
}
}
}
java
try
{
ProcessBuilder pb = new ProcessBuilder("setCursor", "0", "0");
Process p = pb.start();
p.waitFor();
for(int i = 0; i < 30; i++)
{
for(int j = 0; j < 120; j++)
{
Thread.sleep(1);
System.out.print(ContentOnTheScreen[i][j]);
}
}
}
catch (Exception e)
{
System.out.println(e);
}
Windows Terminal / console in recent version of Windows supports ANSI / VT codes so you could achieve movement of character position with System.out.print if your terminal is compatible. You will be able to tell by running this:
public class SetCursor {
private static String CSI = "\u001b[";
private static String at(int row, int col) {
return CSI+row+";"+col+"H";
}
public static void main(String[] args) throws InterruptedException {
System.out.println("HELLO");
System.out.print(at(1,1) + "ABCD");
System.out.print(at(10,5) + "EFGH");
System.out.println("WORLD");
for (int i = 0; i <= 100; i++) {
System.out.print(at(30,20) + " Progress: "+i+"%");
Thread.sleep(100);
}
}
}
It will either print the different values around the screen (running from a Windows Terminal Command Prompt), or if VT codes not supported (such as when running via IDE) the output might look strange:
HELLO
[1;1HABCD[10;5HEFGHWORLD
...
I have a Output class which just prints everything that it gets to print.
public class Output {
private static List<String> textList = new ArrayList<>();
private static Output output = null;
private Output() {
Runnable task = () -> {
int lastIndex = 0;
while (true) {
while (lastIndex < textList.size()) {
System.out.println(lastIndex + " - " + textList.size() + ": " + textList.get(lastIndex));
outputText(textList.get(lastIndex));
lastIndex ++;
}
}
};
new Thread(task).start();
}
private static void outputText(String text) {
synchronized (System.out) {
System.out.println(text);
}
}
public static void say(String text) {
if (output == null) {
output = new Output();
}
textList.add(text);
}
}
When I add something to print, everything works fine:
for (int i = 0; i < 10; i++) {
Output.say("" + i);
}
But when I add a Thread.sleep to the loop it stops on the first output:
for (int i = 0; i < 10; i++) {
Output.say("" + i);
Thread.sleep(100);
}
How can I prevent it? I mean, I'm stopping with sleep just the main thread and not the separate thread.
When you don’t synchronize threads correctly, there is no guaranty that threads see updates made by other threads. They may either completely miss updates or see only parts of them, creating an entirely inconsistent result. Sometimes they may even appear to do the right thing. Without proper synchronization (in the sense of any valid construct specified to be thread safe), this is entirely unpredictable.
Sometimes, the chances of seeing a particular behavior are higher, like in your example. In most runs, the loop without sleep will complete before the other thread even starts its work, whereas inserting sleep raises the chance of lost updates after the second thread has seen values. Once the second thread has seen a value for textList.size(), it might reuse the value forever, evaluating lastIndex < textList.size() to false and executing the equivalent of while(true) { }.
It’s funny that the only place where you inserted a construct for thread safety, is the method outputText that is called by a single thread only (and printing to System.out is synchronized internally in most environments anyway).
Besides, it’s not clear why you are creating an object of type Output that has no relevance here, as all fields and methods are static.
Your code can be corrected and simplified to
public static void main(String[] args) throws InterruptedException {
List<String> textList = new ArrayList<>();
new Thread( () -> {
int index=0;
while(true) synchronized(textList) {
for(; index<textList.size(); index++)
System.out.println(textList.get(index));
}
}).start();
for (int i = 0; i < 10; i++) {
synchronized(textList) {
textList.add(""+i);
}
Thread.sleep(100);
}
}
though it still contains the issues of you original code of never terminating due to the infinite second thread and also burning the CPU with a polling loop. You should let the second thread wait for new items and add a termination condition:
public static void main(String[] args) throws InterruptedException {
List<String> textList = new ArrayList<>();
new Thread( () -> {
synchronized(textList) {
for(int index=0; ; index++) {
while(index>=textList.size()) try {
textList.wait();
} catch(InterruptedException ex) { return; }
final String item = textList.get(index);
if(item==null) break;
System.out.println(item);
}
}
}).start();
for (int i = 0; i < 10; i++) {
synchronized(textList) {
textList.add(""+i);
textList.notify();
}
Thread.sleep(100);
}
synchronized(textList) {
textList.add(null);
textList.notify();
}
}
This is still only an academic example that you shouldn’t use in real life code. There are classes for thread safe data exchange provided by the Java API removing the burden of implementing such things yourself.
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
String endMarker = "END-OF-QUEUE"; // the queue does not allow null
new Thread( () -> {
for(;;) try {
String item = queue.take();
if(item == endMarker) break;// don't use == for ordinary strings
System.out.println(item);
} catch(InterruptedException ex) { return; }
}).start();
for (int i = 0; i < 10; i++) {
queue.put(""+i);
Thread.sleep(100);
}
queue.put(endMarker);
}
I am new to Java. I am trying to create a Java Program that has the ability to retry itself when an exception occur in the program (which work fine). Now the problem I have now is in the for loop. In this code, when something went wrong in the for loop, the program itself will jump out of that loop and go to the catch method. After that if the retry is less than MAX_RETRIES, then the program will relaunch from the beginning. This is what I am struggling with. What I want is let say if there is an exception occur in the for loop when printing let say 5, I want the program to retry where the exception in the for loop occur not relaunch from the beginning. Are there ways to do it? I am struggling with this for a while and cannot seems to find a way to do it. Help and code for reference will be appreciated. This is the best way I can think of to simplify my code. In my real application, the for loop I have right now is to Iterate though a list of record from the database.
main.java
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
try {
while (retry <= MAX_RETRIES) {
//method1
//stuff code
//more code
//method2
for (int i = 0; i < 11; i++) {
System.out.println("i");
}
}
System.out.println("-----Finish Process-----");
break;
} catch (Exception e) {
e.printlnStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
I think it solve your problem
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
while (retry <= MAX_RETRIES) {
try {
//method1
//stuff code
//more code
//method2
int i=0;
while (i < 11) {
try {
System.out.println(i);
i++;
} catch (Exception e) {
e.printStackTrace();
i++;
if (i == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
retry++;
} catch (Exception e) {
e.printStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
System.out.println("-----Finish Process-----");
}
}
I have an idea that might help. I can't show any example code, but it might be possible to set up a flag/signal1 after you complete each step in executing the program. Then, when the program retries, it can automatically skip to that point in code where it last stopped.
1: I don't know what it's called in java
I am new to multi threading. Literally. And I am pretty new to Java overall. HOwever, I am making a simulation and the thread seem to be working well except I occasionally have the program become unresponsive and once it said out of memory error. I assume this is because I am creating too many threads? At the point it normally does this I have over 2000 threads running at the same time. I can adjust the code (i.e reduce the number of customers or increase time between ticks) to release the pressure on the system but I am wondering if there is something I could be doing to help ease the burden within each thread itself. I'm pretty sure it isn't a deadlock since the code runs fine if I do the above but run it for longer so the same amount of customers come through. I will show the relevant parts of the code and if more is required I am happy to put this up. Please I don't understand this very well, so some very simple and helpful explanations would be greatly appreciated, since if the comment is too complex I probably wont' know how to implement it.
This is the main class that creates the thread.
CheckoutFloor checkoutFloor = new CheckoutFloor();
checkoutFloor.addCheckoutOperators(checkoutOperators);
int tick = 0;
int customers = 0;
while (tick < simulationTime) {
for (int i = 0; i < 2; i++) {
Random rand = new Random();
int random = rand.nextInt(100) + 1;
if (random <= 50) {
customerRunnable customer = new customerRunnable(checkoutFloor);
Thread t = new Thread(customer);
t.start();
tick++;
}
else {
tick++;
}
Here is the runnable code:
public void run() {
try {
customer.addRandomShopTime();
while (customer.shopTime > 0) {
Thread.sleep(1);
customer.setShopTime();
}
CheckoutOperator checkoutOperator = checkoutFloor.weightedCheckoutDeterminator();
checkoutOperator.addCustomer(customer);
while (customer.checkoutTime > 0) {
Thread.sleep(1);
if (checkoutOperator.customerList.get(0) == customer) {
customer.setCheckoutTime();
}
}
checkoutOperator.removeCurrentCustomer();
} catch (InterruptedException e) {
}
And here are the relevant methods.
public synchronized void addCustomer(Customer newCustomer) {
customerList.add(newCustomer);
System.out.println("no. of customers" + counter);
counter++;
}
public synchronized CheckoutOperator weightedCheckoutDeterminator() {
int totalCustomers = 0;
int totalCustomersAdj = 0;
for (int i = 0; i < checkoutOpList.size(); i++) {
totalCustomers += getCheckoutOperator(i).getCustomerListLength();
}
if (totalCustomers == 0) {
return getCheckoutOperator(0);
} else {
totalCustomersAdj = (checkoutOpList.size() * totalCustomers) - totalCustomers;
int randomNumber = 0;
try {
randomNumber = new Random().nextInt(totalCustomersAdj) + 1;
} catch (IllegalArgumentException ex) {
return checkoutOpList.get(0);
}
for (int i = 0; i < checkoutOpList.size(); i++) {
int operatorCustLength = (getCheckoutOperator(i).getCustomerListLength());
if (randomNumber <= (totalCustomers - operatorCustLength)) {
return getCheckoutOperator(i);
} else {
randomNumber = randomNumber - (totalCustomers - operatorCustLength);
}
}
return checkoutOpList.get(0); //HOPEFULLY UNREACHABLE!!!
}
I'm just wondering if, due to my lack of knowledge, there is anything I am missing that woudl help the flow a bit more and help it run faster?
[edit: I should add that under normal conditions I would never have 2000 threads running and this is me pushing the system to the max. I suspect that this IS the problem and I guess I am asking if there is something else I am missing due to my lack of knowledge. I just don't like the idea that if someone changes the code to make it more intensive that it might crash.].
Since Java cannot unload native libraries when once used (in Matlab; see SO question), i am trying to call 2 GUI classes from within Matlab. I am working on grabbing an image from camera and then saving it on disk. I want to use one Java class for communicating with camera while another class (GUI) is still open in Matlab. Is this possible? Here's the code:
1.
public class GUI
{
public static void main(String[] args)
{
// Just open up the window and start things running
MainWindow mWindow = new MainWindow();
}
public static void main2()
{
MainWindow.grabImage(0);
}
}
2.
public class MainWindow
{
static volatile int commandVal;
Thread updateThread;
static CameraImage cImage;
static int fs_c =1;
MainWindow(){
JFrame main_f = new JFrame("M");
main_f.getContentPane().setLayout(new BorderLayout());
main_f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
main_f.getContentPane().add(tabPane1, "Center");
main_f.pack();
main_f.setVisible(true);
kkk = 1;
mySerial = new CameraSerial(cWindow.getPort());
}
}
3.
public static void grabImage(int commandVal){
while (MainWindow.kkk == 1) {
if (MainWindow.fs_c == 1) {
MainWindow.commandVal = 5;
}
if (MainWindow.commandVal == 5 || MainWindow.commandVal == 6){
cImage.sendFrame(0);
JFileChooser save_d = new JFileChooser();
File saveFile = save_d.getSelectedFile();
cImage.writeImage(saveFile + ".jpg");
MainWindow.fs_c = 0;
MainWindow.commandVal = 0;
mySerial.write("\r");
System.out.println("Camera Ready...");
break;
}
else if (commandVal == -1) {
MainWindow.commandVal = 0;
mySerial.write("\r");
status_t.setText("Camera Ready...");
}
else {
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
}
}
From Matlab I'm calling first Gui.main([]), and then Gui.main2(). It works for the first time. But when I call Gui.main2() again, Matlab does nothing. I think it's a bad code somewhere. Thanks for replying!
Just an assumption without having more information:
This check:
if (MainWindow.fs_c == 1) {
MainWindow.commandVal = 5;
}
And later this (note that commandVal would be 5 after the check succeeded for the first time):
MainWindow.fs_c = 0;
MainWindow.commandVal = 0;
Here's the problem:
In the first run, commandVal is set to 5, assuming MainWindow.fs_c is initially 1.
Thus MainWindow.fs_c = 0; is executed.
In the second run MainWindow.fs_c == 1 is false (MainWindow.fs_c is now 0) and MainWindow.commandVal was also set to 0. Thus the method doesn't do anything, except sleeping for 100 milliseconds.