I don't have much experience with threading in Java. How can I get the value of String ft all way from inside Runnable(){} to use it in main().
public class testInner {
public static void main (String[] args){
Outer out =new Outer();
out.makeinner();
System.out.println("main :" + out.getft());
}
}
public class Outer {
private volatile String ft;
public String getft(){
return ft;
}
public void makeinner(){
inner in = new inner();
in.changeOuter();
}
public class inner{
public void changeOuter(){
new Thread(new Runnable(){
public void run(){
ft = "what?";
System.out.println("run :" + ft);
}
}).start();
}
}
}
Result when compiled:
main :null
run :what?
Threads are executed in parallel, so you can't be sure the thread has been successfully executed when you do System.out.println("main :" + out.getft());. This is why you get null, the thread didn't edit that variable yet.
If you want to be sure the thread finishes the execution, use join:
public class inner{
public void changeOuter(){
Thread myThread = new Thread(new Runnable(){
public void run(){
ft = "what?";
System.out.println("run :" + ft);
}
});
myThread.start();
myThread.join(); // wait for the thread to finish before returning
}
}
Related
hi guys I'm trying to learn the basics of java multithreading, while studying I had found this exercise
public class Test {
public static void main(String[] args) {
Runnable rrr = () -> Thread.currentThread().setName(args[0]);
new print(rrr).start();
}
}
The exercise asks to implement the print class so that the following test print the value of args[0]
public class print extends Thread{
public print(Runnable rrr) {
}
public void run()
{
System.out.println("run() called by " + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName());
}
}
This is my implementation, is right?
The Runnable rrr parameter is nowhere used. So the code isn't executed anywhere. You'll need to change the code to something like
public class print extends Thread{
private Runnable rrr;
public print(Runnable rrr) {
this.rrr = rrr;
}
public void run()
{
rrr.run(); // this runs "Thread.currentThread().setName(args[0])"
System.out.println("run() called by " + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName());
}
}
to have it work.
Simpler approach:
Thread t = new Thread(() -> {
System.out.println("Thread name is " + Thread.currentThread().getName());
});
t.setName("Peter");
t.start();
Thread name is Peter
No need for Runnable for the constructor when a thread starts it directly call run method
In an interview I was asked to come up with an approach which will ensure that while thread T1 and T3 can access a method of a class, T2 cannot access the method.
I am unable to provide any solution to this. Could you please provide an example with an explanation?
I have later come up with the following solution. Is it efficient?
package JavaProgramming;
public class EligibleThread implements Runnable {
public void method1() {
System.out.println("Hello");
}
public static void main(String[] args) {
EligibleThread t1 = new EligibleThread();
EligibleThread t2 = new EligibleThread();
Thread t11 = new Thread(t1, "t1");
Thread t22 = new Thread(t2, "t2");
t11.start();
t22.start();
}
public void run() {
if (Thread.currentThread().getName() != "t2") {
method1();
} else{
try {
throw new Exception("Access is denied");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
You can use protected modifier, like following code. T1 can call aMethod() by extending Main class, but T2 can't call aMethod().
public class Main {
protected void aMethod() {
}
}
class T1 extends Main implements Runnable{
#Override
public void run() {
aMethod();
}
}
class T2 implements Runnable{
#Override
public void run() {
// here can't call Main.aMethod()
}
}
This is my code which i tried but my main class is not there because i don't know how to use that one
//first thread
class firstthread extends Thread
{
public void run(){
for(int i=0;i<1000;i++)
{
System.out.println(i);
}}
}
//second thread
class secondthread extends Thread
{
public void run(){
for(int i=0;i<1000;i++)
{
System.out.println(i);
}}
}
First overide the run method and then create the object of thread class in main()
and call start method.
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
for(int y=0;y<1000;y++)
{
System.out.println(y);
}
};
}.start();
}
}
Whatever you have written is incomplete code, to create a thread you need to extend Thread class or implement Runnable interface and then override its public void run() method.
To create a thread you need to override the method public void run
Then to start the threads you need to call its start() method.
A simple complete example
class MyThread extends Thread {
String name;
public void run(){
for(int i=0;i<1000;i++) {
System.out.println("Thread name :: "+name+" : "i);
}
}
}
class Main{
public static void main(String args[]){
MyThread t1 = new MyThread();
t1.name = "Thread ONE";
MyThread t2 = new MyThread();
t2.name = "Thread TWO";
MyThread t3 = new MyThread();
t3.name = "Thread THREE";
t1.start();
t2.start();
t3.start();
}
}
You can't just put some code in your class body.
You need a method to have the code in, the method being run() in case of thread.
Instead of copy-pasting the code, I'll point you to the official documentation where you can find some examples.
Sample program given below. Since there is no synchronization code, there output is mixed from the three threads
public class ThreadTest implements Runnable{
#Override
public void run() {
System.out.print(Thread.currentThread().getId() + ": ");
for(int i=0;i<100;i++)
System.out.print(i + ", ");
System.out.println();
}
public static void main(String[] args) {
for(int i=0;i<3;i++){
new Thread(new ThreadTest()).start();
}
}
}
suppose we have these classes and read the comments
class Work {
void doWork(){ }
void commit(){}
}
class MyRunable implements Runnable {
run(){
Work work=new Work();
work.doWork();
//i can't write work.commit() here, because sometimes i want Thread runs both methods
//and sometimes runs only doWork()
}
}
class Tasks{
main(){
MyRunable myRunable=new MyRunable();
Thread t=new Thread(myRunable);
t.start();
//suppose now i need to call commit() method by the same thread (t)
//how can i do that
}
}
also i don't want to use constructor to determine if i want to call both method or not
You could try using a thread pool with a single thread and keep enqueuing methods as needed:
class Tasks {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
final Work work = new Work();
exec.submit(new Runnable() {
public void run() {
work.doWork();
}
});
// later
exec.submit(new Runnable() {
public void run() {
work.commit();
}
});
}
}
This way, both methods will be executed in a sequence by the same thread, but separately.
Add parameter to your class MyRunnable. Call this parameter "runingMode". It could be an enum:
enum RunningMode {
DO_WORK {
public void work(Work work) {
work.doWork();
}
},
COMMIT {
public void work(Work work) {
work.commit();
}
};
public abstract void work();
}
Now your class MyRunnable should have list of modes:
class MyRunable implements Runnable {
private Collection<RunningMode> modes;
MyRunable(Collection<RunningMode> modes) {
this.modes = modes;
}
}
Implement run() method as following:
Work work=new Work();
for (RunningMode mode : modes) {
mode.work(work);
}
work.doWork();
Create instance of your class passing to it the mode you currently need:
MyRunable myRunable=new MyRunable(Arrays.asList(RunningMode.DO_WORK, RunningMode.COMMIT));
You could use an anonymous class.
final boolean condition = ...
Thread t = new Thread(new Runnable() {
public void run() {
Work work=new Work();
work.doWork();
if(condition)
work.commit();
}});
t.start();
I believe variables used in static main method should be also static as well.
The problem is that I cannot use this in this method at all. If I remember correctly, I have to initiate thread with commnad myThread = new ThreaD(this).
The below codes produces an error because I used this in thread initiation.
What have I done wrong here?
package app;
public class Server implements Runnable{
static Thread myThread;
public void run() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
System.out.println("Good morning");
myThread = new Thread(this);
}
}
You can't use this because main is a static method, this refers to the current instance and there is none. You can create a Runnable object that you can pass into the thread:
myThread = new Thread(new Server());
myThread.start();
That will cause whatever you put in the Server class' run method to be executed by myThread.
There are two separate concepts here, the Thread and the Runnable. The Runnable specifies what work needs to be done, the Thread is the mechanism that executes the Runnable. Although Thread has a run method that you can extend, you can ignore that and use a separate Runnable.
Change new Thread(this) to new Thread(new Server()):
package app;
public class Server implements Runnable{
static Thread myThread;
public void run() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
System.out.println("Good morning");
myThread = new Thread(new Server());
}
}
class SimpleThread extends Thread {
public SimpleThread(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " thread: " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! thread: " + getName());
}
}
class TwoThreadsTest {
public static void main (String[] args) {
new SimpleThread("test1").start();
new SimpleThread("test2").start();
}
}