How would I go about mocking the class USBConnection with mockito when I have asynchronous methods, threads and loops?
The basic idea behind this prorotype is that the USBConnection should send data to the variable speed in Arduino.class every second and Arduino prints out the value every second.
The class USBConnection is the one I want to mock. Any tips and guidelines to achieve this is appreciated.
public abstract class Arduino {
private static int speed;
public static void setSpeed(int a) {
speed = a;
}
public static int getSpeed(){
return speed;
}
public static void printSpeed(){
System.out.println(speed);
}
public static void main(String[] args) throws InterruptedException {
USBConnection usb = new USBConnection();
Thread usbThread = new Thread(usb);
usbThread.start();
while(true){
printSpeed();
Thread.sleep(1000);
}
}}
the interface
interface USB {
public void sendSpeed(int a); }
the class we need to mock:
class USBConnection implements Runnable, USB {
public void sendSpeed(int a){
Arduino.setSpeed(a);
}
#Override
public void run() {
int i = 0;
while(true){
sendSpeed(i);
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
Based on some trial and error and Christoper's comments I decided to not use mockito in this way mentioned above.
We redesigned the software architecture and wont mock the class with loops or threads.
Related
I am trying to implement an Annotation based Event System for my OpenGL Game Engine. I apply the #EventListener Annotation on the method which I want to be called like this:
#EventListener(type = Type.COLLISION)
public void OnCollision(CollisionEvent data)
{
System.out.println("HI");
}
The class in which this method sits implements an Empty Interface:
public class Sprite implements EventHandler
The EventDispatcher class:
public class EventDispatcher
{
private static List<EventHandler> registered = new ArrayList<EventHandler>();
public static void register(EventHandler EventHandler)
{
if (!registered.contains(EventHandler))
{
registered.add(EventHandler);
}
}
public static void unregister(EventHandler EventHandler)
{
if (registered.contains(EventHandler))
{
registered.remove(EventHandler);
}
}
public static List<EventHandler> getRegistered()
{
return registered;
}
public static void dispatch(final Event event)
{
new Thread()
{
#Override
public void run()
{
call(event);
}
}.start();
}
private static void call(final Event event)
{
for (EventHandler registered : getRegistered())
{
Method[] methods = registered.getClass().getMethods();
for (int i = 0; i < methods.length; i++)
{
System.out.println("Annotation Being Checked");
if (methods[i].isAnnotationPresent(EventListener.class))
{
System.out.println("Has Annotation");
Class<?>[] methodParams = methods[i].getParameterTypes();
if (methodParams.length < 1)
{
continue;
}
if (!event.getClass().getSimpleName().equals(methodParams[0].getSimpleName()))
{
continue;
}
try
{
methods[i].invoke(registered.getClass().newInstance(), event);
} catch (Exception exception)
{
System.err.println(exception);
}
} else System.out.println("No Annotation");
}
}
}
}
But when I run the program, It always prints out
Annotation Being Checked
No Annotation
multiple Times.
Can someone help? If more information is needed, please ask and I will edit the Question.
I setup a project based on your example and it's working fine. You will however see some "No Annotation" messages as your code evaluates all methods of the Sprite event handler. Even if you don't implement any additional methods other than OnCollision each class will inherit default methods from Object such as equals, hashCode or toString.
Test class:
public class SpriteTest {
public static void main(String[] args) {
EventDispatcher.register(new Sprite());
CollisionEvent collisionEvent = new CollisionEvent();
EventDispatcher.dispatch(collisionEvent);
}
}
Apart from that there are some obvious flaws in your code:
Don't use stateful static members (EventDispatcher.registered) unless you know what you're doing and are aware of the multithreading aspects that come with it
You store instances of EventHandler but only use the class information and create a new instance on the fly - why not register the class instead of an instance directly
You fork new Threads for each to be dispatched event. This is very bad practice as thread creation is a costly operation. Use a thread pool instead and submit runnables or callables
You check if the class' simple names match to see if a handler method is applicable. This will break when using inheritance and should be replaced by Class.isAssignableFrom
In general usage of annotations here is questionable. You're probably better off using dedicated interfaces for the different event types. Instead of a generic EventHandler there could be a CollisionEventHandler and so on...
Rough implementation idea
public interface CollisionEventHandler extends EventHandler {
void onCollision(CollisionEvent event);
}
public class Sprite implements CollisionEventHandler {
public void onCollision(CollisionEvent data) {
System.out.println("HI");
}
}
public class EventDispatcher {
...
static void call(final CollisionEvent event) {
getRegistered().stream()
.filter(handler -> handler instanceof CollisionEventHandler)
.map(handler -> (CollisionEventHandler) handler)
.forEach(handler -> handler.onCollision(event));
}
}
To handle different types of events you will need different call/dispatch methods. Maybe you can use the Visitor pattern (though I'm not a fan of it).
I have two classes that I'm trying to manipulate one variable with, as an example
public class A {
public static void main(String[] args) {
while(game_over[0] == false) {
System.out.println("in the while-loop");
}
System.out.println("out of the while-loop");
}
static boolean[] game_over = {false};
}
and
public class B {
public boolean[] game_over;
public printBoard(boolean[] game_over) {
this.game_over = game_over;
}
public void run() {
for (int i = 0; i < 10; i++) {
// do something
}
game_over[0] = true;
System.out.println("GAME OVER");
}
}
The code snippets provided are not meant to be actual workable code, I'm more concerned with the concept. In my program, class A creates a thread that utilizes class B, and I want class B to affect the variable 'game_over' such that the while-loop in class A will be affected by the change... any idea how I can successfully update the variable? Thanks.
Don't use an array for this, that makes it harder to ensure a data-race free application.
Since you want to be able to pass around the game_over flag as an independent object, the easiest way to achieve a correct multi-threaded application is to use the AtomicBoolean class.
import java.util.concurrent.atomic.AtomicBoolean;
class B {
private AtomicBoolean game_over;
public B(AtomicBoolean game_over) {
this.game_over = game_over;
}
public void run() {
// do stuff
game_over.set(true);
}
}
and in your class A:
public class A {
static AtomicBoolean game_over = new AtomicBoolean();
public static void main(String[] args) {
B b = new B();
Thread t = new Thread(b);
t.start();
while (!game_over.get()) {
System.out.println("in the while-loop");
}
System.out.println("out of the while-loop");
}
}
I have two threads. One is a producer (class Deliver), second is consumer (class Produce). I want to simulate door producer. So producer deliver wood that consumer can produce a door. But i do not real get how to communicate between those two threads. Now when i run my program only wood is delivered but doors are not produced. I do not get why.
public class Deliver implements Runnable {
private static int MAX_STOCKPILE = 15;
private Integer wood;
public Deliver(Integer wood) {
this.wood = wood;
new Thread(this, "Deliver").start();
}
public synchronized void deliver() throws InterruptedException{
Thread.sleep(500);
if (wood < MAX_STOCKPILE) {
wood++;
System.out.println("Wood delivered" + " | Wood stockpile: " + wood);
notify();
}
else {
wait();
}
}
#Override
public void run() {
while (true) {
try {
deliver();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Produce implements Runnable{
private Integer wood;
public Produce(Integer wood) {
this.wood = wood;
new Thread(this, "Produce").start();
}
public synchronized void produce() throws InterruptedException{
Thread.sleep(1000);
if (wood == 10) {
wood -= 10; //produce
System.out.println("Doors produced");
notify();
}
else {
wait();
}
}
#Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Integer wood = 0;
new Deliver(wood);
new Produce(wood);
}
}
Now when i run my program only wood is delivered but doors are not produced. I do not get why
There are multiple issues with your code :
When you mark an instance method as synchronized, any thread entering that method will obtain a lock on this (i.e the instance on which the method was called). Since this in Deliver refers to a Deliver instance and this in Produce refers to a Produce instance, the wait and notify calls are practically useless in this case as they are not interested in the same objects.
The golden rule to remember in Java is that it uses pass-by-value semantics. Primitives and references are therefore always passed by value. While you may assume that both Deliver and Produce will be modifying the same Integer passed to them from main, that is not the case.
That said, I would highly recommend that you consider using something like an ArrayBlockingQueue for solving this instead of reinventing the wheel with wait and notify.
Change
if (wood == 10) {
to
if (wood >= 10) {
in case the thread doesn't catch it when it == 10
Something to note is that Integer is immutable.
When you change the reference to the Integer you are creating a new object which has no relationship to the previous object.
What you want this an object which is shared between the two threads so when you change the value (but not the reference) they are looking at the same value.
e.g.
wood -= 10;
is the same as
wood = Integer.valueOf(wood.intValue() - 10);
I suggest using AtomicInteger and making the reference to it final to ensure you don't accidentally try to change the reference.
As Andrew Jenkins suggests; if you lock, notify/wait on unrelated objects, you don't have any thread safety. Once you have a shared object, you have to lock, notify/wait on that shared object.
I'll throw my solution into the mix, taking into account Peter Lawrey's advice about using AtomicInteger.
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger wood = new AtomicInteger(0);
new Deliver(wood);
new Produce(wood);
}
}
public class Deliver implements Runnable {
private static int MAX_STOCKPILE = 15;
private final AtomicInteger wood;
public Deliver(AtomicInteger wood) {
this.wood = wood;
new Thread(this, "Deliver").start();
}
public void deliver() throws InterruptedException{
Thread.sleep(500);
synchronized(wood) {
if (wood.intValue() < MAX_STOCKPILE) {
wood.addAndGet(1);
System.out.println("Wood delivered" + " | Wood stockpile: " + wood);
wood.notify();
} else {
wood.wait();
}
}
}
#Override
public void run() {
while (true) {
try {
deliver();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Produce implements Runnable{
private final AtomicInteger wood;
public Produce(AtomicInteger wood) {
this.wood = wood;
new Thread(this, "Produce").start();
}
public void produce() throws InterruptedException{
synchronized(wood) {
if (wood.intValue() >= 10) {
wood.addAndGet(-10); //produce
System.out.println("Doors produced");
wood.notify();
}
else {
wood.wait();
}
}
}
#Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Key changes:
We use a mutable object to communicate between threads (AtomicInteger).
We synchronize on the mutable object, not the thread being run.
Folks. I'm newbie in network programming and come across the following issue. I need to write the server which can maintain a connection with more than one client simultaneously. What I've written is the following:
Main class:
public class Main {
public static void main(String args[]) throws Exception{
ConnectionUtils.waitForClients();
}
}
ConnectionUtils class:
public class ConnectionUtils {
private static ServerSocket server;
static{
try {
server = new ServerSocket(54321);
} catch (Exception e) {
}
}
private static Runnable acceptor = new Runnable() {
#Override
public void run() {
try {
Client c = new Client(server.accept());
new Thread(acceptor).start();
c.sendLine("Hello client \n");
} catch (Exception e) {
}
}
};
public static void waitForClients(){
Thread clientAcceptor = new Thread(acceptor);
clientAcceptor.start();
}
}
and it works, more-or-less. But what is the downside of that approach? I suspect there're too much disadvantage, but I can't catch their.
The problem is that you creating an infinite number of threads where threads are expensive resources. You should be using a ThreadPool to limit the number of threads created in your program.
Consider using Executors instead of using this low-level code, In Oracle documentation about Executors, there is an example similar to what you doing. Check it out!
Heh interesting. I wouldn't expect it to be wrong but it sure isn't how I'd write it.
I'd probably have 1 thread in an infinite (semi-infinite with stop condition) loop that accepts and spawn threads, rather than something that looks like a recursive method but isn't. However as far as I can see it's not wrong.
Having said that, if you don't use your main thread for anything, why not do something like (and keep in mind i'm not a network programmer either)
public class ConnectionUtils {
protected boolean stop = false;
public static void waitForClients() {
while (!stop) {
Client c = new Client(server.accept());
new Thread(new ClientDelegate(c)).start();
}
}
}
public static class ClientDelegate implements Runnable {
private Client client;
public ClientDelegate(Client c) { this.client = c; }
public static void run() {
c.sendLine("Hello client\n");
}
}
I implemented a simple timer with Observer pattern. I wanted to terminate the main function when 5 minutes passes while it is running. Basically what I need is a simple one shot timeout functionality. How can I achieve this? My code is not working. Below is the timer class
public class OneShotTimer extends Observable implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(30);
} catch (Exception e) {
// TODO: handle exception
System.out.println("Exception in timer");
}
notifyObservers();
}
In main class's constructor I initialize that timer.
public GreenOverlayMain(){
timer = new OneShotTimer();
timer.addObserver(this);
Thread t = new Thread(timer, "mythread");
t.start();
}
However the update() function of main class is never executed because timeout never happens. MainClass implements Observer interface. Below is the update function.
#Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
System.gc();
System.exit(0);
}
This example print update end finish execution.
public static void main(String[] args){
//scheduler executor is a lot more sophisticated solution
final ScheduledExecutorService sheduler = Executors.newScheduledThreadPool(1);
class MyO extends Observable {
public void trackChanged(){
setChanged(); //this method is protected in super class
}
};
//must be final because it used in nested class
final MyO o = new MyO();
o.addObserver(new Observer() {
#Override
public void update(Observable o, Object arg) {
//your processing here
System.out.println("update");
sheduler.shutdown();
}
});
sheduler.schedule(new Runnable() {
#Override
public void run() {
o.trackChanged();
o.notifyObservers();
}
}, 3, TimeUnit.SECONDS); //set any timout
}
Here is a reusable OneShotTimer.
new OneShotTimer(3, () -> setChange());
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class OneShotTimer
{
final ScheduledExecutorService sheduler = Executors.newScheduledThreadPool(1);
/// Call [callback] after [duration] seconds.
public OneShotTimer(int duration, OneShotCallback callback)
{
sheduler.schedule(() -> _callback(callback), duration, TimeUnit.SECONDS);
}
void _callback(OneShotCallback callback)
{
sheduler.shutdown();
callback.callback();
}
public interface OneShotCallback
{
void callback();
}
}