Interrupt a thread from another thread in java? - java

I have to create a program that simulate a bomb... The user has 5 seconds to digit the right code, if he can't, the bomb explodes.
class Codice implements Runnable{
String code;
#Override
public void run() {
code = JOptionPane.showInputDialog("Inserire codice disinnesco:");
if(code.equals(Bomba.check)) {
Bomba.s = "true";
JOptionPane.showMessageDialog(null, "Bomba disinnescata");
}
System.out.println(Bomba.s);
}
}
class Esplosione implements Runnable{
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!Bomba.s.equals("true")) {
JOptionPane.showMessageDialog(null, "BOOM!");
}
}
}
public class Bomba {
static String s = "false";
static String check = "123456";
public static void main(String[] args) throws IOException {
Codice c = new Codice();
Esplosione ex = new Esplosione();
Thread t1 = new Thread(c);
Thread t2 = new Thread(ex);
t1.start();
t2.start();
}
}
With this code i can insert the code, and if it's right the bomb doesn't explodes and the program finish. If 5 seconds passes, the message "boom" appears but the first thread doeasn't stop... How can i do?

There are many ways to coordinate between threads; interrupting is one way. Here is an example using Thread.interrupt. It dispenses with your state variable s, which becomes unnecessary:
import javax.swing.*;
import java.io.*;
class Codice implements Runnable {
String code;
Thread other;
Codice(Thread other) {
this.other = other;
}
#Override
public void run() {
code = JOptionPane.showInputDialog("Inserire codice disinnesco:");
if(code.equals(Bomba.check)) {
other.interrupt();
JOptionPane.showMessageDialog(null, "Bomba disinnescata");
}
}
}
class Esplosione implements Runnable {
#Override
public void run() {
try {
Thread.sleep(5000);
JOptionPane.showMessageDialog(null, "BOOM!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Bomba {
static String check = "123456";
public static void main(String[] args) throws IOException {
Esplosione ex = new Esplosione();
Thread t2 = new Thread(ex);
Codice c = new Codice(t2);
Thread t1 = new Thread(c);
t1.start();
t2.start();
}
}

Related

Concurrency issue with threads

I have a simple code, consisting of 4 threads (2 modify the data and 2 read the data). I just wrote this sample code to play around with Semaphor and I am not sure why I get ava.base/java.util.ArrayList$Itr.checkForComodification exception? Here are the source code and thanks for any insights.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static class InnerWriterSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerWriterSemaphoreThread(List<String> list, Semaphore w) {
fList = list;
fWriteSem = w;
}
private void prune() {
System.out.println(Thread.currentThread().getName()+" in prune()..");
for (String s : fList) {
fList.remove(s);
}
}
#Override
public void run() {
String name = Thread.currentThread().getName();
String text;
while (true) {
text = RandomTextGenerator.getRandomSNumbertring();
try {
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphore to write..");
Thread.sleep(0L,4);
}
if (fList.size() > 10) {
prune();
}
fList.add(text);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
fWriteSem.release();// notify readers that write has completed
System.out.println(name+" finished writing, releasing semaphore..");
}
}//while()
}//run()
}//WriterSemaphoreThread
public static class InnerReaderSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerReaderSemaphoreThread(List<String> list,Semaphore w) {
fList = list;
fWriteSem = w;
}
private void sleep(){
try{
Thread.sleep(0L, 4);
}catch(InterruptedException e){
e.printStackTrace();
}
}
#Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name + " in run()..");
try {
while(fList.isEmpty()){
System.out.println(name+" list is empty, going to sleep..");
sleep();
}
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphor to read..");
Thread.sleep(0l,4);
}
for (String text : fList) {
System.out.println(name + " reading from list " + text);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
finally{
fWriteSem.release(); //Notify threads who want to write to the list
System.out.println(name+" finished reading, releasing semaphore and going to sleep..");
sleep();
}
}
}
}//ReaderSemaphoreThread
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Semaphore r = new Semaphore(1);
Thread th1 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 1");
Thread th2 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 2");
Thread th3 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 3");
Thread th4 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 4");
th2.start();
th4.start();
th1.start();
th3.start();
}
}
Above is the sample source code
As #assylias mentioned in comment it happens when you remove elements from list in foreach loop. Just replace
for (String s : fList) {
fList.remove(s);
}
with
fList.clear();

Java wait() notify()

I have the following code:
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}}
class ThreadB extends Thread{
#Override
public void run(){
synchronized(this){
notify();
}
}}
I'm pretty new to wait/notifyThreads and I need to find a way to wait before the notify() of Thread B until I call it explicitly from another class, preferably at first from a test case, later on from detached web service class. I don't get it, can you please help me out?
import java.lang.InterruptedException;
public class ThreadRunner {
public static void main(String[] args){
ThreadA a = new ThreadA();
ThreadB b = new ThreadB(a);
b.start();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
}
}
class ThreadA extends Thread {
String name = "threadA";
public void run() {
try {
synchronized (this) {
wait();
}
System.out.println(name + " " + "notified!");
} catch(InterruptedException e) {
// TODO: something
}
}
}
class ThreadB extends Thread {
ThreadA a;
String name = "threadB";
public ThreadB(ThreadA a) {
this.a = a;
}
#Override
public void run(){
a.start();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
synchronized (a) {
System.out.println(name + " " + "trying to notify A!");
a.notify();
}
}
}
If you want to wait for a task to be completed, I suggest using Java Concurrency API way:
public class WaitATaskExample {
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newSingleThreadExecutor();
Future<?> future = service.submit(() -> {
// your task here
Thread.sleep(5000);
return null;
});
try {
future.get(); // blocking call
} catch (InterruptedException | ExecutionException e) {
// handle exceptions
}
} finally {
if (service != null) {
service.shutdown();
}
}
}
}
Another approach using CountDownLatch:
public class WaitATaskExample {
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
Callable<Object> waitingTask = () -> {
latch.await(); // wait
return null;
};
Callable<Object> notifier = () -> {
Thread.sleep(2_000);
latch.countDown(); // notify
return null;
};
service.submit(waitingTask);
service.submit(notifier);
} finally {
if (service != null) {
service.shutdown();
}
}
}
}

How to implement runnable with java

I am trying to create a program that will carry on running automatically without me having to do anything. I am a bit confused on how to implement runnable in java so I can create a thread that will go to sleep for a certain period of time and then run the re-run the program after the sleep period is over.
public class work {
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.information();
}
private ConfigurationBuilder OAuthBuilder() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("dy1Vcv3iGYTqFif6m4oYpGBhq");
cb.setOAuthConsumerSecret("wKKJ1XOPZbxX0hywDycDcZf40qxfHvkDXYdINWYXGUH04qU0ha");
cb.setOAuthAccessToken("4850486261-49Eqv5mogjooJr8lm86hB20QRUpxeHq5iIzBLks");
cb.setOAuthAccessTokenSecret("QLeIKTTxJOwpSX4zEasREtGcXcqr0mY8wk5hRZKYrH5pd");
return cb;
}
public void information() throws IOException, InterruptedException {
ConfigurationBuilder cb = OAuthBuilder();
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
User user = twitter.showUser("ec12327");
Query query = new Query("gym fanatic");
query.setCount(100);
query.lang("en");
String rawJSON =null ;
String statusfile = null;
int i=0;
try {
QueryResult result = twitter.search(query);
for(int z = 0;z<5;z++){
for( Status status : result.getTweets()){
System.out.println("#" + status.getUser().getScreenName() + ":" + status.getText());
rawJSON = TwitterObjectFactory.getRawJSON(status);
statusfile = "results" + z +".txt";
storeJSON(rawJSON, statusfile);
i++;
}
}
System.out.println(i);
}
catch(TwitterException e) {
System.out.println("Get timeline: " + e + " Status code: " + e.getStatusCode());
if(e.getErrorCode() == 88){
Thread.sleep(900);
information();
}
}
} catch (TwitterException e) {
if (e.getErrorCode() == 88) {
System.err.println("Rate Limit exceeded!!!!!!");
Thread.sleep(90);
information();
try {
long time = e.getRateLimitStatus().getSecondsUntilReset();
if (time > 0)
Thread.sleep(900000);
information();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
private static void storeJSON(String rawJSON, String fileName) throws IOException {
FileWriter fileWriter = null;
try
{
fileWriter = new FileWriter(fileName, true);
fileWriter.write(rawJSON);
fileWriter.write("\n");
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
} finally {
if(fileWriter!=null) {
fileWriter.close();
}
}
}
}
You have severable options to implement a thread in Java.
Implementing Runnable
When a class implements the Runnable interface, he has to override the run() method. This runnable can be passed to the constructor of a Thread. This thread can then be executed using the start() method. If you'd like to have this thread run forever and sleep, you could do something like the following:
public class HelloRunnable implements Runnable {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Extending Thread
Thread itself also has a run() method. When extending thread, you can override the Thread's run() method and provide your own implementation. Then you'd have to instantiate your own custom thread, and start it in the same way. Again, like the previous you could do this:
public class HelloThread extends Thread {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
Source: Oracle documentation
Building on the previous answer, you need to either extend Thread or implement Runnable on your Work class. Extending Thread is probably easier.
public class work extends Thread {
public void run() {
// your app will run forever, consider a break mechanism
while(true) {
// sleep for a while, otherwise you'll max your CPU
Thread.sleep( 1000 );
this.information();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.start();
}
// ... rest of your class
}
public static void main(String[] args){
Thread thread = new Thread(runnable); // create new thread instance
thread.start(); // start thread
}
public static Runnable runnable = new Runnable(){
#Override
public void run(){
final int DELAY = 500;
while(true){
try{
// Code goes here;
Thread.sleep(DELAY)
} catch(Exception e){
e.printStackTrace();
}
}
}
}

Semaphores and counting with java

I've written out my code signalling north and southbound cars crossing a one lane bridge but I'm having some trouble with counting.
It should read like: a car is waiting, then maybe several, with one crossing at a time and increasing every time. Instead it repeats the same three numbers every time.
Should I declare my count int differently or am I increasing it incorrectly? I've tried many different ways and can't quite find the true issue.
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SingleLaneBridge {
public static void main(String[] args) {
final Bridge bridge = new Bridge();
Thread th1 = new Thread( new Runnable() {
#Override
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread th2 = new Thread( new Runnable() {
#Override
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
th1.start();
th2.start();
}
}
class Bridge {
private final Semaphore semaphore;
public Bridge() {
semaphore = new Semaphore(1);
}
public void crossBridge(Car car) {
try {
System.out.printf("Car %s is trying to cross the bridge. \n",car.count++);
semaphore.acquire();
System.out.printf("Car %s is crossing the bridge. \n",car.count++);
Thread.sleep(5000);
} catch(InterruptedException iex) {
iex.printStackTrace();
} finally {
System.out.printf(" Car %s has crossed the bridge. \n",car.count++);
semaphore.release();
}
}
}
class Car implements Runnable {
int count = 0;
private String name;
private Bridge bridge;
public Car(Bridge bridge) {
this.bridge = bridge;
}
public void run() {
bridge.crossBridge(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The reason why it repeats the three numbers again and again is that, the Car instances are created afresh every time and the count is initialized to 0.
To overcome this, define the Car class as follows to get the atomic counting as multiple Threads (Cars) are involved here,
class Car implements Runnable {
private static AtomicInteger globalCarID = new AtomicInteger(0);
int count;
...
public Car(Bridge bridge) {
this.bridge = bridge;
count = globalCarID.incrementAndGet();
}
}
And modify the System.out.printf's in crossBridge() method to not to increment the count,
Below is the complete code that might serve what you wanted,
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class SingleLaneBridge {
public static void main(String[] args) {
final Bridge bridge = new Bridge();
Thread th1 = new Thread( new Runnable() {
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread th2 = new Thread( new Runnable() {
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
th1.start();
th2.start();
}
}
class Bridge {
private final Semaphore semaphore;
public Bridge() {
semaphore = new Semaphore(1);
}
public void crossBridge(Car car) {
try {
System.out.printf("Car %s is trying to cross the bridge. \n",car.count);
semaphore.acquire();
System.out.printf("Car %s is crossing the bridge. \n",car.count);
Thread.sleep(500);
} catch(InterruptedException iex) {
iex.printStackTrace();
} finally {
System.out.printf(" Car %s has crossed the bridge. \n",car.count);
semaphore.release();
}
}
}
class Car implements Runnable {
private static AtomicInteger globalCarID = new AtomicInteger(0);
int count;
private String name;
private Bridge bridge;
public Car(Bridge bridge) {
this.bridge = bridge;
count = globalCarID.incrementAndGet();
}
public void run() {
bridge.crossBridge(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Java Wait/Notify not working

So I have been working on a simple wait/notify example in Java and for some reason I have not been able to get it to run properly. If anyone is able to see what might be the issue It would be very appreciated!
public class ThreadDemonstration
{
private String str = null;
Thread stringCreator = new Thread(new Runnable()
{
public void run()
{
synchronized(this)
{
str = "I have text";
notify();
}
}
});
private Thread stringUser = new Thread(new Runnable()
{
public void run()
{
synchronized(this)
{
if(str == null)
{
try {
System.out.println("str is null, I need help from stringCreator");
wait();
System.out.println(str);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
});
public static void main (String [] args)
{
ThreadDemonstration td = new ThreadDemonstration();
td.stringUser.start();
td.stringCreator.start();
}
}
My current output is:
str is null, I need help from stringCreator
So for some reason the thread stringCreator does not wake up the stringUser or am I missing something else entirely?
Thank you!
Your blocks are synchronized over different objects. They should be synchronized over a common object, for example the monitor object below:
public class ThreadDemonstration
{
private String str = null;
private final Object monitor = new Object();
Thread stringCreator = new Thread(new Runnable()
{
public void run()
{
synchronized(monitor)
{
str = "I have text";
monitor.notify();
}
}
});
private Thread stringUser = new Thread(new Runnable()
{
public void run()
{
synchronized(monitor)
{
while(str == null) //changed from if to while. This allows you to wait again if the thread gets woken up by something other than the appropriate notify.
{
try {
System.out.println("str is null, I need help from stringCreator");
monitor.wait();
//removed print statement from here
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println(str); //added print statement here. str is guaranteed to not be null here.
}
}
});
In order to avoid creating a separate object for synchronization, you can use synchronized(ThreadDemonstration.this) or synchronized(ThreadDemonstration.class) for example.
Try this :
private Thread stringUser = new Thread(new Runnable() {
//-----
System.out.println("str is null, I need help from stringCreator");
notify();
wait(100);
System.out.println(str);
//----
});
You need to use the wait and notify of the same instance in order for it to work. Since you create two different objects (2 instances of Runnable) it will not work. I've written a simple example using two different classes using the main class' instance for the intrinsic lock. You could also us a 'dummy object' (Object lock = new Object) for this.
public class ThreadDemonstration {
private static String text;
public ThreadDemonstration(){
Thread user = new Thread(new StringUser(this));
Thread creator = new Thread(new StringCreator(this));
user.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
creator.start();
}
public class StringCreator implements Runnable{
private Object lock;
StringCreator(Object lock){
this.lock = lock;
}
#Override
public void run() {
synchronized(lock){
text = "Yeeeehaaaaa";
lock.notify();
}
}
}
public class StringUser implements Runnable{
private Object lock;
StringUser(Object lock){
this.lock = lock;
}
#Override
public void run() {
synchronized(lock){
if((text == null)){
System.out.println("I need help!");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(text);
}
}
}
public static void main(String[] args){
new ThreadDemonstration();
}
}

Categories