import java.util.Scanner;
import static java.lang.Thread.sleep;
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name){
threadName = name;
}
public void run() {
System.out.println("asd");
}
public void start ()
{
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
class RunnableDemo1 implements Runnable {
private Thread t;
private String threadName;
RunnableDemo1( String name){
threadName = name;
}
public void run() {
Scanner in = new Scanner(System.in);
System.out.print("Enter here:");
String x = in.nextLine();
System.out.println(x);
}
public void start ()
{
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
RunnableDemo1 R1 = new RunnableDemo1( "Thread-1");
R1.start();
sleep(1000);
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
Println will print a line to the command prompt but in.nexLine() (also tried in.next() does not recognize it. Is there any way I am able to print a string to the command prompt and have the scanner recognize it? Or something similar?
System.out.println shouldn't send anything to the server since it sends the String to the standard out only, usually the console, unless you've re-routed the standard out, something that I don't recommend that you do. Instead you need to actually send something to the server, perhaps in your notifyObservers method, but hard to say without your mcve.
In all this remains a very incomplete question until you improve it.
Edit: yes the Observable API shows that public void notifyObservers(Object arg) has an overload that accepts an Object parameter. Why not pass your String in there?
Edit 2: OK, you're confused, because that's not how you have one class communicate with another. Printing something out to the console will not trigger the System.in to update in another thread. Again, do what I stated above.
Related
I have the next sample I am trying to run, but sometimes it runs fine, another it is not exiting the loop. I can imagine only that for some reason values are skipping.
By skipping the values I mean the flags meant to notify the loop in the class Flasher to exit, which are brought from class engine, ass well the flags meant to notify the loop in class Engine from class Flasher.
This is how I understood it could run the best possible and simplest way, but what is going on?
Can you please help?
//Main class:
public class Flasher {
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
engine en1 = new engine("ZaikoBaiko");
engine en2 = new engine("MiliVaninili");
en1.start();
en2.start();
int Terminator2 = 0;
while(!en1.Terminator||!en2.Terminator)
{
}
System.out.println(" owns the last word");
en1.roboCop = true;
en2.roboCop = true;
}
}
//Thread Class:
public class engine extends Thread
{
public String OB;
public boolean Terminator = true;
public boolean roboCop = false;
private Thread t;
engine(String name)
{
OB = name;
Terminator = false;
}
#Override
public void run()
{
int x = 0;
while(x<100)
{
System.out.println(x+":"+OB);
x++;
}
Terminator = true;
while(!roboCop){}
}
#Override
public void start()
{
if(t==null)
{
t = new Thread(this,OB);
t.start();
}
}
}
The JVM is caching your variables. You need to add volatile to your check variables (Terminator, roboCop). This will ensure that all threads write/read the newest value to/from main memory.
For a detailed explanation here is a similar question!
I'm trying to make room reservation system, I have multi clients access same reservation method.
so I put this method into thread class and I want to make one ReentrantLock to allow one client to access the reservation method.. also this method will be called from another class.
the problem I got is nullPointerException.
this is my code:
public class server {
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(9800);
ReentrantLock roomLock = new ReentrantLock();
while(true){
System.out.println("Server ready to recive clint... ");
Socket k = s.accept();
System.out.println("Clint "+ s.getInetAddress() +" accept " );
new myThread(k,roomLock).start();
}
}
}
class myThread extends Thread{
Socket s;
public static ReentrantLock roomLock;
public myThread(Socket so, ReentrantLock rl) {
this.s = so;
this.roomLock = rl;
}
#Override
public void run(){
}
public static Boolean resRoom(String usname,JRootPane rootPane,Date date1,Date date2,Boolean chbox,int sp){
Boolean stv = true;
if(roomLock.tryLock()){
// my critical section
roomLock.unlock();
}
return stv;
}
}
the method should be static to access it from another class
So I am learning to create my own SerialConsole in nachos (Java). I learned using Semaphore.P() and Semaphore.V() to wait for user input. Everything is going well until I tried to make a function like getch() in C's conio.h.
The problem is, whenever I called Semaphore.P(), even though the Semaphore.V() is called, it will always wait for Enter key to be pressed before it resume the program. I wanted the program to resume whenever I press a key.
Below is some code I tried.
Console.java
public class Console {
private SerialConsole console;
private Semaphore sem = new Semaphore(0);
private Runnable send, recv;
private char tempChar;
public Console() {
console = Machine.console();
send = new Runnable() {
#Override
public void run() {
sem.V();
}
};
recv = new Runnable() {
#Override
public void run() {
tempChar = (char) console.readByte();
sem.V();
}
};
console.setInterruptHandlers(recv, send);
}
public String nextLine() {
String result = "";
do {
sem.P();
if (tempChar != '\n') result += tempChar;
} while(tempChar != '\n');
return result;
}
public char getch() {
sem.P();
return tempChar;
}
}
Main.java
public class Main {
private Console console;
public Main() {
console = new Console();
char c = console.getch();
System.out.println(c);
}
}
Is there anything I have missed or is there any way to programmatically press Enter key or something?
PS: java.awt.Robot can't be used inside a nachos project.
Any help would be appreciated.
I am working on a console based Java application. I've to show suggestions to user for selecting a database. I am using Scanner for reading input and a separate thread for checking if input contains TAB in order to print the suggestions.
UPDATE
As per below answer, I added synchronized block to code and the Exception is gone. However, I don't see any suggestions printed on the console. Below is my current code:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Test {
private static List<String> suggestions = new ArrayList<>();
private static final Object lock = new Object();
public static void main(String[] arguments) {
suggestions.add("H2");
suggestions.add("Mongo");
suggestions.add("MySQL");
suggestions.add("Oracle");
suggestions.add("PostgreSQL");
suggestions.add("SQLite");
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a database name, press TAB for suggestions");
new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
if (scanner.hasNext()) {
String input = scanner.next();
if (input.contains("\\t")) {
System.out.println(getSuggestions(input));
}
}
}
}
}
}).start();
synchronized (lock) {
String selectedDatabase = scanner.nextLine();
System.out.println(selectedDatabase);
}
}
private static List<String> getSuggestions(String input) {
List<String> possibleSuggestions = new ArrayList<>();
for (String suggestion : suggestions) {
if (suggestion.startsWith(input)) {
possibleSuggestions.add(suggestion);
}
}
return possibleSuggestions;
}
}
Could somebody please help?
Simply put, Scanner is not a thread-safe class and you are using it in two different threads.
You instantiate the scanner it in the Main thread and use it in the other one. In the background the constructor of Scanner might have initialized fields that are not necessarily synced to the other thread.
And while the other thread runs you do a scanner.nextLine() in the Main thread which might execute at the exact same time as the other thread doing a scanner.hasNext(), leading to concurrent access.
You need a way to synchronize access to the scanner (everywhere), e.g. by means of a lock.
synchronized (lock) {
if (scanner.hasNext()) {
String input = scanner.next();
if (input.contains("\\t")) {
System.out.println("ok");
}
}
}
where the lock is a static field you synchronize on:
private static final Object lock = new Object();
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);
}});