while debugging the java Multithreading program i put breakpoints. after start method is invoking the control is not going to run menthod can you please let me know the debug procedure.
sample code
class Test extends Thread {
public static void main(String[] args) {
try {
Thread t = new Thread(new Test());
t.start();
t.start();
} catch (Exception e) {
System.out.print("e ");
}
}
public void run() {
for(int i = 0; i < 2; i++)
System.out.print(Thread.currentThread().getName() + " ");
}
}
Debugger starts with main thread, since your breakpoint is in main thread.
t.start() spawns a new thread.
But the debugger will continue with the main thread itself.
If you want to debug the newly created thread, then you have to set a breakpoint in run() method also.Then the debugger control goes to the newly created thread, but it is invisible to the user.
If you want to see the control in run() method of newly created thread, then you have to follow the below steps -
Put a breakpoint in run() method along with the main() method.
Start debugging the program till you hit the statement t.start().
After completing t.start(), go to "Debug" view. There you will find 2 threads running.(You can find the "Debug" view in eclipse by going to "Window -> Show View -> Debug").
First one is main thread
Second one is newly created thread (e.g. [Thread-1] )
Click on the second thread to see the control in run method.
After completion of your thread execution, go to the "Debug" view again and click on the main thread to continue with the main thread debugging.
Note: If you continue with the main thread after 3rd step towards the end of the thread, then you will not be able to debug your new thread.
Related
I perhaps was not clear enough in this question
https://stackoverflow.com/questions/62958507/how-to-have-intellij-play-just-the-thread-i-am-debugging-like-eclipse-does
so it was marked as duplicate of
switching between threads in Intellij Idea
but I did that and changed my breakpoint suspend policy to 'Thread'. This did not change the behavior at all so I am providing code now here.
Here is my code for this test
public class TestDebugger {
private static final Logger log = LoggerFactory.getLogger(TestDebugger.class);
private Executor exec = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws InterruptedException {
new TestDebugger().start();
Thread.sleep(10000000);
}
private void start() {
Runnable r = new Runnable() {
#Override
public void run() {
log.info("logger BREAKPOINT A thread="+Thread.currentThread().getName());
log.info("logger A");
log.info("logger A");
log.info("logger A");
log.info("logger A");
log.info("logger A");
log.info("logger A");
log.info("logger BREAKPOINT B"+Thread.currentThread().getName());
}
};
exec.execute(r);
exec.execute(r);
exec.execute(r);
}
}
I start up the program and threads 1,2,3 all stop on breakpoint A. This part is good. Then I hit the play button while on thread 1 and behind my back, it switches threads!!! This is very annoying and not desired. In fact, I feel the eclipse debugger here works MUCH better as that is the default behavior.
In fact, if I hit play 6 times for all 3 threads, this is the logs...
NOTE: If I remove the other log statements in the middle, it starts working again as I would expect.......weird
INFO: logger BREAKPOINT A thread=pool-2-thread-1
INFO: logger BREAKPOINT A thread=pool-2-thread-3
INFO: logger BREAKPOINT Bpool-2-thread-3
INFO: logger BREAKPOINT Bpool-2-thread-1
INFO: logger BREAKPOINT A thread=pool-2-thread-2
INFO: logger BREAKPOINT Bpool-2-thread-2
The first TWO logs should both be thread 1 but instead it's thread 1, then thread 3....grrrr. Anyway to get this to work?
thanks,
Dean
This behavior is by design and there is no way to change it at the moment. Source: developer responsible for IntelliJ IDEA debugger.
This is the program output:
Program Begin
1 - Starting
2 - Task started
A - Started something
Program End
B - Completed something
3 - Task completed with result: 123
Question: As far i understand when it comes to await process is going back to main context so in this case to Main and then go back to await when it's finished so "A - Started something" should be after "Program End". Why this one line was shown? From my understanding when it comes to away it should immediatly go back to main context.
static void Main(string[] args)
{
Console.WriteLine("Program Begin");
DoAsAsync();
Console.WriteLine("Program End");
Console.ReadLine();
}
static async void DoAsAsync()
{
Console.WriteLine("1 - Starting");
var t = Task.Factory.StartNew<int>(DoSomethingThatTakesTime);
Console.WriteLine("2 - Task started");
var result = await t;
Console.WriteLine("3 - Task completed with result: " + result);
}
static int DoSomethingThatTakesTime()
{
Console.WriteLine("A - Started something");
Thread.Sleep(1000);
Console.WriteLine("B - Completed something");
return 123;
}
As far i understand when it comes to await process is going back to main context so in this case to Main and then go back to await when it's finished so "A - Started something" should be after "Program End".
That is what that thread is doing; the main thread is returning to the Main method.
However, StartNew will (in this case) execute its work on a thread pool thread, which runs independently from the main thread. So, you might see "A - Started something" before or after "Program End".
When it comes to await, first the task get triggered, here it is "DoSomethingThatTakesTime". And then goes back to calling method to perform the next task/execution (here in your case it is Main()).
This will be much meaning full if you have another await in the main.
look into below example. very well explained.
https://msdn.microsoft.com/en-us/library/mt674892.aspx
You may see a different result, if you call thread sleep before first print statement.
I'am very new to threading and quite unclear as to why this is happening in my code, when I click on a button that verifies hyperlinks in my document, I start a new thread that does the verification once it starts I want to disable the ribbon button and enable it again after thread finished but this is not happening and I dont know what is the mistake .Here is what I have tried so far:
public class Alpha :Ribbon1
{
// This method that will be called when the thread is started
public void Beta()
{
foreach() { //do something } after this loop ,enable the button again
button.enable=true //not applying
} }
private void button_Click(object sender, RibbonControlEventArgs e)
{
Alpha oAlpha = new Alpha();
// Create the thread object, passing in the Alpha.Beta method
Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
// MessageBox.Show("Please wait till the document is checked for invalid links");
// Start the thread
oThread.Start();
button7.Label = "Pls wait";
button7.Enabled = false;
}
Ribbon needs to be rendered again after enable/disable for change to take effect, you can do this by calling IRibbonUI.Invalidate()
I've seen a few references on Stack Overflow about using the Timer Class to do what I want but I'm not convinced it's the right solution to the problem.
Basically, I have a button (in .NET 4.0) that when clicked will go through a few different subroutines and do certain things:
Restart some services
Launch a command line application that finishes automatically
Launch a second command line application that finishes automatically
Launch a third command line application that finishes automatically
The problem I have right now is that the program just goes through each thing and fires it off as quickly as possible - not a problem except that the third command line application must only fire after the first three are completed.
I had a sleep call in the code, except that this froze the UI and I have a status bar on this application that I wanted to have update to let the user know things are occurring.
I was thinking about a Timer object but I'm not sure that would actually cause there to be a pause before doing the next thing.
I'm using a Process.Start method to fire off the command line applications, so it doesn't actually raise an event. Should I just have my subroutine raise an event and then have the third Process.Start method wait for that event to fire before it goes?
This small snippet might help you. Try to get the idea and implement your own code.
try
{
Process myProcess;
myProcess = Process.Start("Notepad.exe");
while (true)
{
if (!myProcess.HasExited)
{
// Discard cached information about the process.
myProcess.Refresh();
// Print working set to console.
Console.WriteLine("Physical Memory Usage: "
+ myProcess.WorkingSet.ToString());
// Wait 2 seconds.
Thread.Sleep(2000);
}
else {
break;
}
}
// Close process by sending a close message to its main window.
myProcess.CloseMainWindow();
// Free resources associated with process.
myProcess.Close();
}
catch(Exception e)
{
Console.WriteLine("The following exception was raised: ");
Console.WriteLine(e.Message);
}
I'm currently using WCF in monotouch to call an existing service and a custom UIAlertView.
The problem is that if I create an UIAlertView as class instance and the I do the following:
public override void ViewDidAppear()
{
_alertView.Message = "Loading...";
_alertView.Show();
_client.GetDataAsync("test");
_client.GetDataCompleted += GetDataCompletedDelegate;
base.ViewDidAppear();
}
void GetDataCompletedDelegate(object sender, GetDataEventArgs)
{
// do someting with data
_alertView.Hide();
}
it works but this advice is written in console : UIAlertView: wait_fences: failed to receive reply: 10004003
else, if I try to run this code:
public override void ViewDidAppear()
{
using(CustomAV _alertView = new CustomAV())
{
_alertView.Message = "Loading...";
_alertView.Show();
_client.GetDataAsync("test");
_client.GetDataCompleted += delegate{
InvokeOnMainThread(delegate{
// do someting with data
_alertView.Hide();
});
};
}
base.ViewDidAppear();
}
the first time the code run, but now alert is shown. The second time the simulator can't startup. Couldn't register "com.yourcompany.wcftest" with the bootstrap server. Error: unknown error code. This generally means that another instance of this process was already running or is hung in the debugger.StackTrace. In this case I have to reboot the machine.
Thank you in advance.
EDIT:
Thank you Geoff, I've checked my code and into GetDataCompletedDelegate I've inserted a function that runs inside the UI Thread.
InvokeOnMainThread(delegate{
doSomething();
});
private void doSomething()
{
// do stuff here
_alertView.Hide();
}
The fency error continues to appear. If I use your solution inside doSomething() method, it works
_alertView.InvokeOnMainThread(delegate{
_alertView.Hide();
});
Why? Maybe I didn't understand, but in the first snippet of code do something() works in the UI thread!! Isn't true?
You have 2 seperate problems here.
1: _alertView.Hide () is not running on the UI thread (this is what causes the fences error)
2: In your second example you're disposing the UIAlertVeiw immediately after creating it, but you have a instance delegate dangled off it. This crashes the runtime in a hard way, and then when you run it again since the old crashed process is still running the simulator wont let you start a second instance.
Use case #1 but do _alterView.InvokeOnMainThread (delegate { _alertView.Hide (); });