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
Related
I create Runner in two ways. But ::new doesn't work.
Then I marked the debugger point at Runner1's construct. The debugger point didn't work either.
Who can tell me why?
Is there any difference with Runnable in Runner1::new?
Here is my code.
public static void main(String[] args) {
Runnable n1 = Runner1::new;
Runnable n2 = new Runner2();
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(n1);
executorService.submit(n2);
while (true) {
}
}
public static class Runner1 implements Runnable {
public Runner1() {
System.out.println("construct 1");
}
#Override
public void run() {
System.out.println("hello1");
}
}
public static class Runner2 implements Runnable {
public Runner2() {
System.out.println("construct 2");
}
#Override
public void run() {
System.out.println("hello2");
}
}
Runnable n1 = Runner1::new is roughly analogous to this code:
Runnable n1 = () -> new Runner1();
In other words, the Runnable n1 will instantiate a Runner1 when it's called.
That's not what you want to do, instead you want to instantiate a Runner1 and assign that new Runner1 to n1, just as you did with n2.
Using the ::new syntax as a Runnable is not very useful, because a Runnable doesn't have a return value. In other words: your n1 Runnable would instantiate a Runner1 but not make it accessible to any other code.
The way ::new is usually used is to implement something like a Supplier like this:
Supplier<List<Object>> emptyListSuppier = ArrayList::new;
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
}
}
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();
}
}
}
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();
}
}
I want the main method to print out the value x, which is returned by running threads. How can I do it? Hope that my question makes sense.
import java.*;
public class ServerStudentThread extends Thread
{
public ServerStudentThread(Socket x) {
client = x;
}
public void run()
{
//Do something here and return an integer,
// for example **x**
}
public static void main(String args[]) throws Exception {
// ...
// I want to print out x value here.
// But as you can see, x disappears after thread finish its job.
}
}
You would have to make x a field in the ServerStudentThread class, not a local variable. then add a method in the class like getValue() that returns x. From the main method, after you create the thread, run it, call the getValue() mehod on the class to print get the value of x and print it.
If you are using java 5 there is an Callable Interface.kindly look at this link
http://java-x.blogspot.com/2006/11/java-5-concurrency-callable-and-future.html
// Code pasted from the link
public class CallableTester {
public static void main(String[] args) {
Callable<Integer> callable = new CallableImpl(2);
ExecutorService executor = new ScheduledThreadPoolExecutor(5);
Future<Integer> future = executor.submit(callable);
try {
System.out.println("Future value: " + future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class CallableImpl implements Callable<Integer> {
private int myName;
CallableImpl(int i){
myName = i;
}
public Integer call() {
for(int i = 0; i < 10; i++) {
System.out.println("Thread : " + getMyName() + " I is : " + i);
}
return new Integer(getMyName());
}
public int getMyName() {
return myName;
}
public void setMyName(int myName) {
this.myName = myName;
}
}
You should create thread (call Thread t = new ServerStudentThread(), then call t.start() then you should wait until the tread is done. For example call t.join().