Okay, so I've basically done the hardest workaround I could think of for the program that I'm working on and now have everything working....except the program itself.
So, here's the code I'm working with:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
Thread thread = new Thread(new thread2());
public void run() {
thread.start();
double startTime = System.nanoTime();
SortingStuff ss = new SortingStuff();
ss.setVisible(true);
double endTime = System.nanoTime();
double elapsedTime = endTime - startTime;
System.out.println("This operation took " + elapsedTime + " nanoseconds, which is :" + ((elapsedTime / 1000000) / 1000) + " seconds."); // This will be better later
}
});
}
And then the thread2 runnable is something like this:
public static class thread2 implements Runnable{
public void run() {
System.out.println("thread " +Thread.currentThread().getName());
}
Now, if I wanted to call a static method from the thread created, how could I go about doing that? I have a method called "bubbleSort" that I just can't get to work within the created thread. Help?
public static void bubbleSort(final String numbers[], final JButton numButton[]){
//Is the skeleton for the method, however I can't put it in the run area, and I can't seem to access the other thread from outside of where it's run. UGH!
./Frustrated
Running a static method from a class, even one that implements runnable, will not run on that thread, it will run from whichever thread called the static method. Anything that you want to happen in that thread needs to get called from run().
thread2 mythread = new thread2();
new Thread(mythread).start(); //Spawns new thread
thread2.bubbleSort(args); //Runs in this thread, not the spawned one
In response to the comment, I assume you were having problems because you couldn't pass your arguments to the run method. You need to get that data to the thread either before it starts, or through some sort of data stream(file, socket, etc). Here I use the constructor, but it can also be done with a setData(data here) function.
public class Example implements Runnable {
private dataObject args;
public Example(dataObject input) {
args = input;
}
public void dosort(dataObject sortArg){contents}
public void run() {
dosort(args);
}
}
public static void main(stuff) {
Example myExample = new Example(data);
//alternate example
//myExample.setData(data);
new Thread(myExample).start();
}
Related
I am working on a multi-thread program. Can someone please help me on how to implement the sleep method within my program. I have never used it and the requirement is that the run method uses the sleep method. I did start 4 threads and checked the outlined ranges. and I should Modify the Finder class so its run method utilizes the sleep method. I have never used the sleep method.
import static java.lang.System.out;
class Range
{
int start;
int end;
Range(int s, int e)
{
start = s;
end = e;
}
boolean contains(int x)
{
return end - start >=0;
}
}
class Finder implements Runnable
{
#Override
public void run()
{
}
}
public class ThreadTest implements Runnable
{
static void log(Object o){out.print(o);}
static void logLn(Object o){out.println(o);}
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* #see Thread#run()
*/
#Override
public void run()
{
logLn("Running main");
}
static Range myRange = new Range(100, 500);
public static void main(String[] args)
{
if (myRange.contains(300))
{
System.out.println ("You\'re within the correct range.");
}
Finder fc = new Finder();
Thread t1= new Thread(fc);
t1.start();
Thread t2= new Thread(fc);
t2.start();
Thread t3 = new Thread(fc);
t3.start();
Thread t4 = new Thread(fc);
t4.start();
Runnable myRunnable = new Runnable(){
public void run(){
System.out.println("Runnable running");
}
};
myRunnable.run();
}
}
Sleep is a static method provided by the Thread class via Thread.sleep(1000L) where the value you pass is a Long representing milliseconds. Implementing a sleep method doesn't make much sense but calling Thread.sleep() will suspend the current thread that is executing that call.
So my guess is that you are supposed to call Thread.sleep within the run function of Finder.
EDIT
Implementing would simply be calling what I explained:
class Finder implements Runnable{
#Override
public void run(){
System.out.println("Thread " + Thread.currentThread().getId() + " sleeping");
Thread.sleep(1500L);
System.out.println("Thread " + Thread.currentThread().getId() + " awake");
}
}
public class TestSynchronization {
public static void main(String[] args) {
ThreadTest[] threads = new ThreadTest[10];
int i = 0;
for(Thread th : threads) {
th = new Thread(Integer.toString(i++));
th.start();
}
}
class ThreadTest extends Thread {
TestSynchronization ts = new TestSynchronization();
public /*synchronized */void run() {
synchronized(this) {
ts.testingOneThreadEntry(this);
System.out.println(new Date());
System.out.println("Hey! I just came out and it was fun... ");
this.notify();
}
}
}
private synchronized void testingOneThreadEntry(Thread threadInside) {
System.out.println(threadInside.getName() + " is in");
System.out.println("Hey! I am inside and I am enjoying");
try {
threadInside.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I am not able to start the ThreadTest instances.
I expect that ThreadTest's run method be executed as soon as the line th.start(); is executed, the one inside main method.
When I run the program, I see niether my system.out nor any exception.
I debugged also, but could see loop runs 10 times.
You just started a Thread, not a ThreadTest. Thread's run() method does nothing. Instead, create and start() a ThreadTest.
for(ThreadTest th : threads) {
th = new ThreadTest(Integer.toString(i++));
th.start();
}
You'll also need a one-arg constructor in your ThreadTest class that will take the String you're passing to it.
public ThreadTest(String msg){
super(msg);
}
You'll also need to make the ThreadTest class static so you can access that nested class from the static main method.
static class ThreadTest extends Thread {
However, you'll wind up will all Threads waiting. As written, this code will call wait inside every Thread, but it will never get to notify. The notify method must be called on the Thread to be notified, from another Thread. If it's waiting, then it can never notify itself.
You have array of ThreadTest (thread) class which is not used.
I assume you wanted this:
public static void main(String[] args) {
ThreadTest[] threads = new ThreadTest[10];
int i = 0;
for(int i=0;i<threads.length;i++) {
threads[i] = new ThreadTest();
threads[i].start();
}
}
If I do the following, I will be able to create an object as a thread and run it.
class ThreadTest
{
public static voic main(String[] args)
{
HelloThread hello = new HelloThread();
Thread t = new Thread(hello);
t.start();
}
}
class HelloThread extends Thread
{
public void run()
{
System.out.println(" Hello ");
}
}
Now, if my HelloThread class has a another method call runThisPlease(), how are we supposed to run it with a thread?
Example:
class HelloThread extends Thread
{
public void run()
{
System.out.println(" Hello ");
}
public void runThisPlease(String input)
{
System.out.println (" Using thread on another class method: " + input );
}
}
Que: When I try Thread t = new Thread(hello.runThisPlease());, it doesn't work. So how can we call the method runThisPlease() using a thread?
Edit: Argument needed in method for runThisPlease();
In java 8 you can use
Thread t = new Thread(hello::runThisPlease);
hello::runThisPlease will be converted to a Runnable with a run method that calls hello.runThisPlease();.
If your want to call a method, that needs parameters, e.g. System.out.println, you can of course use a normal lambda expression too:
final String parameter = "hello world";
Thread t = new Thread(() -> System.out.println(parameter));
If you use a java version < 8, you can of course replace the method reference / lambda expression with anonymus inner classes that extend Runnable (which is what a java8 compiler does, AFAIK), see other answers.
However you can also use a anonymus inner class that extends Thread:
final HelloThread hello = //...
Thread t = new Thread() {
#Override
public void run() {
hello.runThisPlease();
}
};
Simply calling the runThisPlease() from within the run() method will make it part of a new thread.
Try this:
class HelloThread extends Thread
{
public void run()
{
System.out.println(" Hello .. Invoking runThisPlease()");
runThisPlease();
}
public void runThisPlease()
{
System.out.println (" Using thread on another class method ");
}
}
Things are maybe more clear if you use the Runnable interface:
public class HelloThread implements Runnable
{
#Override
public void run() {
// executed when the thread is started
runThisPlease();
}
public void runThisPlease() {...}
}
To launch this call:
Thread t=new Thread(new HelloThread());
t.start();
The Thread class can not see your extra method because it is not part of the Runnable interface.
As a convenience Thread implements Runnable but I don't think it helps in clarity :(
You have to only call this method inside run() method.
public void run(){
System.out.println(" Hello ");
runThisPlease();
}
If you want to pass some argument then you can use below code
String str = "Welcome";
Thread t = new Thread(new Runnable() {
public void run() {
System.out.println(str);
}});
I've created a class called Thread that implements Runnable but I cannot invoke the start() or sleep() methods for some reason. Any time I attempt to do so, I get errors saying that these methods are undefined for the class and suggests that I create them. So I created a new project and copied a sample code to see if there was something wrong with my own code and I received the same errors. Here's the sample code:
class Thread implements Runnable {
private int a;
public Thread (int a) {
this.a = a;
}
public void run() {
for (int i = 1; i <= a; ++i) {
System.out.println(Thread.currentThread().getName() + " is " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
}
and this is my own code:
public class Thread extends PID implements Runnable {
public Thread() {}; // Empty constructor for thread object
public void run() {
Random gen = new Random(); // Generates random values
int sleepTime; // Sleep time
sleepTime = gen.nextInt(60 - 1) + 1; // Generates random sleep time between 1 and 60 seconds
try {
Thread.sleep();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("The thread has been terminated");
}
}
To fix your current error, simply rename your Thread class to MyThread (or whatever), because your Thread class is hiding the java.lang.Thread class.
If you want to stick to Thread, you'll have to use the fully qualified name for java.lang.Thread like this:
try{
java.lang.Thread.sleep(1000);
// ...
Mistakes
Change class name from Thread to MyThread.
run() is called when you invoke start(). Invoke start() using class object.
Thread.sleep(); needs an argument say, sleepTime
Here is the code of what I think you want to do. Tested on Eclipse Juno JDK 1.7
import java.util.Random;
class NewThread implements Runnable {
public NewThread () {
}
public void run() {
Random gen = new Random(); // Generates random values
int sleepTime; // Sleep time
sleepTime = gen.nextInt(60 - 1) + 1; // Generates random sleep time between 1 and 60 seconds
try {
Thread.sleep(sleepTime);
} catch (Exception e) {
System.out.println(e);
}
System.out.println("The thread has been terminated");
}
}
class MyThread {
public static void main(String[] args) {
NewThread t = new NewThread();
Thread t1 = new Thread(t);
t1.start();
}
}
Output
The thread has been terminated
Interface Runnable do not have methods start() and sleep(), so be carefull with it. Interface Runnable only have run() method, and Java API recommends " the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods."
See Java API's Runnable documentation here: http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html
In every other cases, your class should extned class Thread.
I want to restart a thread for some use, for example in the below code.
class Ex13 implements Runnable {
int i = 0;
public void run() {
System.out.println("Running " + ++i);
}
public static void main(String[] args) throws Exception {
Thread th1 = new Thread(new Ex13(), "th1");
th1.start();
//th1.join()
Thread th2 = new Thread(th1);
th2.start();
}
}
When I'm executing the above program , some time i'm getting the output as
Running 1
Running 2
and some time i'm getting only
Running 1
After few run i'm getting only
Running 1 as output.
I'm totally surprise about this behavior. Can any one help me understand this.
if I put the join() then i'm getting only Running 1.
You reuse Thread instance, not Runnable. Thread overwrites its run() method to
public void run() {
if (target != null) {
target.run();
}
}
Where target is the Runnable that you give to the constructor. besides that, Thread has an exit() method that is called by the VM, and this method sets target to null (the reason is this bug). So if your first thread has the chance to finish its execution, its run() method is pretty much empty. Adding th1.join() proves it.
If you want to keep some state, you need to keep reference to your Runnable instance, not the Thread. This way run() method will not be altered.
I don't know why do you need this, but (please note that this code doesn't ensure that th1 is ALWAYS executed before th2, though) :
public static class Ex13 implements Runnable {
AtomicInteger i = new AtomicInteger(0);
CountDownLatch latch;
Ex13(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Running " + i.incrementAndGet());
latch.countDown();
}
}
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(2);
Ex13 r = new Ex13(latch);
Thread th1 = new Thread(r, "th1");
th1.start();
Thread th2 = new Thread(r);
th2.start();
latch.await(); // wait until both theads are executed
System.out.println("Done");
}
You want the incrementing of i to be synchronized, i.e.
public class Ex13 implements Runnable {
int i=0;
public void run() {
System.out.println("Running "+ increment());
}
private synchronized int increment() {
return ++i;
}
}
The Java Tutorial has a very nice explanation of this given a very similar scenario. The problem is that incrementing a variable is not an atomic operation. Each thread needs to read the current state of i before setting it to the new value. Restricting access to incrementing the variable to one thread at a time assures you will get consistent behavior.
To see whats happening in the System.out.println you can also print the thread name:
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
I see you call the two threads with the same runnable object, so they will both use the same "i" variable, in order for you to get Running 1 Running 2 you need to synchronize "i"