Java - ArrayList in another method is empty - java

I'm adding packets to ArrayList in PacketList Class from another classes.
public class PacketList {
public ArrayList<PcapPacket> packets;
public PacketList(){
packets = new ArrayList<PcapPacket>();
}
public void addPacket(PcapPacket packet){
packets.add(packet);
System.out.printf("List size: %d\n", packets.size()); // Size is according to added objects into the list.
}
Until now everything is working fine, but when I create another method to retrieve the list, it's empty..
public ArrayList getList(){
System.out.printf("Size of list in PacketList: %d\n", packets.size()); // Size is 0
return packets;
}
Edit: Sorry, it's actually whole code, only chopped..
import java.util.ArrayList;
import org.jnetpcap.packet.PcapPacket;
public class PacketList {
public ArrayList<PcapPacket> packets;
public PacketList(){
packets = new ArrayList<PcapPacket>();
}
public void addPacket(PcapPacket packet){
System.out.printf("Received packet .. caplen=%-4d\n", packet.getCaptureHeader().caplen());
packets.add(packet);
System.out.printf("List size: %d\n", packets.size()); // Size is according to added objects into the list.
}
public ArrayList getList(){
System.out.printf("Size of list in PacketList: %d\n", packets.size()); // Size is 0
return packets;
}
}
Here I create PacketList
public class ThreadToSwitch implements Runnable {
PacketList pl = new PacketList();
public void run(){
// here I have just pcap init that i did not include, but the packet is ok
PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
public void nextPacket(PcapPacket packet, String user) {
if(packet != null)
pl.addPacket(packet);
}
};
}
This is main where I call getList():
public class SwrMain extends Thread{
public static void main(String[] args) {
Thread tts = new Thread(new ThreadToSwitch());
Thread ttr = new Thread(new ThreadToRouter());
tts.start();
ttr.start();
ArrayList pList;
int myint = -1;
while(myint != 0){
Scanner keyboard = new Scanner(System.in);
myint = keyboard.nextInt();
if(myint == 1){
System.out.printf("\nNumber of packets in list: %d\n", (new PacketList().getList().size()));
}
}
}
}

This is just a guess, but you are probably calling PacketList.getList() from another thread than the one where you add packets. You might be running into some synchronization issue. If that's the case, try switching to a concurrent structure, probably a ConcurrentLinkedQueue.
Seeing your full code (including the code where you read the list) would help diagnose the problem.

So your issue is that you are creating a new packetlist, then asking its size. It is not the same packetlist that you create in the ThreadToSwitch method, but its own instance, created by the default constructor for PacketList when you call new PacketList
public class SwrMain extends Thread{
public static void main(String[] args) {
Thread tts = new Thread(new ThreadToSwitch());
Thread ttr = new Thread(new ThreadToRouter());
tts.start();
ttr.start();
ArrayList pList;
int myint = -1;
while(myint != 0){
Scanner keyboard = new Scanner(System.in);
myint = keyboard.nextInt();
if(myint == 1){
System.out.printf("\nNumber of packets in list: %d\n", (new PacketList().getList().size()));
}
}
}
}
Think of it like this. I have a dog named Fido. I feed Fido until he is a really fat dog. You also have a dog named Fido. No matter how much I feed my Fido, your Fido doesn't get fat. They are different, even though they are named the same thing.
Now, if I were to borrow your Fido for a while and feed him a lot, then your Fido would be fat.

Related

Adding elements to list using getter/setter

Every time I call the method inserimentoVoto to add elements in a list contained in the object Studente, the data is overwritten I know it's easy but I just started to code.
public class Run {
public static void main(String[] args) {
Gestione g = new Gestione();
Studente s = new Studente();
g.inserimentoVoto(s);
}
}
This is the method
public void inserimentoVoto(Studente s) {
Voto v = new Voto();
System.out.println("Insert value");
v.setVoto(scanner.next());
System.out.println("Insert name");
v.setMateria(scanner.next());
v.setDataVoto(new Date());
s.setListaVoti(new ArrayList<Voto>());
s.getListaVoti().add(v);
}
s.setListaVoti(new ArrayList<Voto>());
You are creating a new ArrayList everytime
The above line should be only done once in the Studente class.
public class Studente
{
private ArrayList<Voto> arr = new ArrayList<Voto>();
... Other data ...
public ArrayList<Voto> getListaVoti()
{
return arr;
}
... Other methods ...
}
You do not need a setListaVoti at all - because it's done only once.
In the inserimentoVoto method, you only need
s.getListaVoti().add(v);

Java Multithreading example

I'm a Java student and this is my attempt of implementing a StackExchange (there's a pusher thread and a popper thread, a single stack resource and two controlling Threads for the stack content and time passing).
I was hoping if someone could comment my code for improvements or errors\bad practices, even if the code seems to work.
The main reason of this program was to figure out how to control resource access in a multithreading environment.
I have concerns about the use of the ScheduledThreadPoolExecutor rather than locking(the stack), and my usage of synchronized in the StackExchange class methods(for accessing the stack), I would like to spawn free threads working on a dynamically locked resource. Any advice?
NB:"Format of magic numbers and syso's may be awful for testing porpuses
code here:
package examples;
import java.util.Random;
import java.util.Stack;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.JOptionPane;
public class StackExchange {
/*
* Two Threads playing with a stack, a timer and a controller for the stack that permits to exit
* */
public class Popper implements Runnable
{
StackExchange sEx;
public Popper(StackExchange sex)
{
this.sEx=sex;
}
#Override
public void run() {
System.out.println("Popper: popping!\t"+sEx.getPeek());
sEx.callTheStack(this, null);
}
}
public class Pusher implements Runnable
{
StackExchange sEx;
public Pusher(StackExchange sex)
{
sEx=sex;
}
#Override
public void run() {
System.out.println("Pusher: pushing!\t");
sEx.callTheStack(this, "Hi!");
}
}
public class StackController implements Runnable
{
private Stack<String> theStack;
public int waiting=5;
public StackController(Stack<String> theStack, String name) {
this.theStack = theStack;
Thread.currentThread().setName(name);
}
#Override
public void run()
{
Random rand = new Random();
waiting = rand.nextInt(10);
StringBuilder buffer = new StringBuilder();
int i=0;
for(String string: theStack)
{
buffer.append(string+"\n");
i++;
}
buffer.append("\nFound "+i+" elements\nIWillWait4:\t"+waiting);
System.out.println("\t\t\t\t\t\t\t\t"+Thread.currentThread().getName().toString()+" Says:" + buffer.toString());
if(i>1)
{
System.out.println("ERRER");
System.exit(0);
}
if(i==1 && JOptionPane.showConfirmDialog(null, "found 1 element\nWannaStop?")==0)
System.exit(0);
}
}
public class Timer implements Runnable{
#Override
public void run() {
StackExchange.time++;
System.out.println("Time Passed:\t"+StackExchange.time+" seconds");
}
}
/*
* implementation of the StackExchange class
* */
private Popper popper;
private Pusher pusher;
private StackController stackController;
private StackController secondSC;
private Timer timer;
static int time=0;
private Stack<String> stack;
public StackExchange()
{
timer = new Timer();
stack = new Stack<String>();
pusher = new Pusher(this);
popper = new Popper(this);
stackController = new StackController(this.getStack(), "FirstStackController");
}
public static void main(String[] args) {
StackExchange sex = new StackExchange();
sex.start();
System.out.println("Num of Threads:"+Thread.activeCount());
}
public void start()
{
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(5);
exec.scheduleAtFixedRate(timer, 0, 1, TimeUnit.SECONDS);
exec.scheduleAtFixedRate(pusher, 0, 2, TimeUnit.SECONDS);
exec.scheduleAtFixedRate(popper, 1, 2, TimeUnit.SECONDS);
exec.scheduleAtFixedRate(stackController, 0, stackController.waiting, TimeUnit.SECONDS);
}
public Stack<String >getStack()
{
return this.stack;
}
public void callTheStack(Object caller, String pushedString)
{
synchronized(this)
{
if(caller instanceof Popper)
stack.pop();
else if(caller instanceof Pusher)
stack.push(pushedString);
}
}
public String getPeek()
{
synchronized(this)
{
return stack.peek();
}
}
}
Things that might help:
Don't use java.util.Stack.
A more complete and consistent set of LIFO stack operations is
provided by the Deque interface and its implementations, which should
be used in preference to this class.
http://docs.oracle.com/javase/8/docs/api/java/util/Stack.html
Your nested subclasses of StackExchange are all inner classes so
that means they already have a reference to the containing
StackExchange instance
and its member stack instance, which should be final.
So don't pass them as parameters. This simplifies logic, maintenance,
and GC.
caller instanceof Popper this type of reflection is utterly
unnecessary and breaks object orientation.
You know that Object is too broad a type for callTheStack (weak
name). In fact, you know that the object will be a Runnable, but
more importantly, the Runnable should know what to do already.
Synchronization should be kept minimal to just the critical section that shares data and no more, shown below using the synchronized keyword
or to just the memory boundary, shown below using the volatile keyword
and member variables of a containing class are a great way to share data between threads within the class.
Example
public class StackExchange {
private final Deque<String> stack = new ArrayDeque<>();
private volatile boolean running;
private void consume(String item) {
// ...
}
private String obtain() {
// ...
}
private boolean getPermission() {
// ...
}
// getters, setters, ...
private final Runnable consumer = new Runnable() {
#Override
public void run() {
while (running) {
final String popped;
synchronized(stack) {
popped = stack.pollFirst();
}
consume(popped);
}
}
};
private final Runnable producer = new Runnable() {
#Override
public void run() {
while (running) {
final String pushing = obtain();
synchronized(stack) {
stack.offerFirst(pushing);
}
}
}
};
public static void main(String ... args) {
StackExchange exchange = new StackExchange();
exchange.setRunning(true);
new Thread(exchange.getConsumer()).start();
new Thread(exchange.getProducer()).start();
do {
} while (exchange.getPermission());
exchange.setRunning(false);
}
}
It's a good idea to declare member variables prior to member methods.
I put the Runnable code in anonymous classes to leave the code at the very edge of using lambdas.
The idea behind consume, obtain, and getPermission is to hint at how the code would interact with the business logic that doesn't know about threading. These could be implemented as callbacks or abstract methods.
One good thing about Deque is that it can easily be set up for a FIFO queue.
Just for fun, convert those Runnable instances into lambdas, and make the StackExchange class generic.
Hot question: what other subtypes of Deque<E> might suit, and what advantages or disadvantages would they have? What code changes might need to happen to accommodate them?

Get null value from another object in Java, but get value in own class

When I try to execute this code, after I choose AMD, I got null in value. how it can be happen ?
below is the source code :
[for main]
public class processor{
public int hargapro;
public String nmbarangpro;
public static final Scanner input = new Scanner(System.in);
public String getpro()
{
return nmbarangpro;
}
public int getproharga()
{
return hargapro;
}
public void daftarpro() {
List<String> daftarpro = new ArrayList<>();
daftarpro.add("AMD");
daftarpro.add("Intel");
List<String> nomer = new ArrayList<>();
nomer.add("1. ");
nomer.add("2. ");
System.out.println("Processor yang tersedia :");
for (int i = 0; i < daftarpro.size(); i++) {
System.out.println(nomer.get(i)+daftarpro.get(i));
}
System.out.println("Pilihan anda : ");
int pilih = input.nextInt();
switch(pilih)
{
case 1:
{
System.out.println("Anda membeli Processor AMD");
System.out.println("Seharga Rp 1.200.000");
harga(1200000); //call harga method
namabarang("AMD"); //call namabarang method
System.out.println(getpro()); //[for testing]filled with AMD[ni problem here]
System.out.println(getproharga()); //[for testing][filled with 1200000[no problem here]
break;
}
case 2:
{
System.out.println("Anda membeli Processor AMD");
System.out.println("Seharga Rp 1.200.000");
harga(1500000);
namabarang("Intel");
break;
}
default:
System.out.println("Pilihan tidak tersedia");
daftarpro();
}
}
#Override
public int harga(int hargamasuk) {
return hargapro = hargamasuk;
}
#Override
public String namabarang(String barang) {
return nmbarangpro = barang;
}
public static void main(String[] args) {
processor a = new processor();
a.daftarpro();//get menu from daftarpro()
kasir x = new kasir();
x.semua();//get null in value
}
}
my second files :
public class kasir {
public void semua()
{
processor a = new processor();
System.out.println(a.getpro());
}}
When I try to read value through class kasir, i get x.semua filled with null value. how it can be happen ?
Your semua method creates a new instance of processor which it then reads from:
public void semua()
{
processor a = new processor();
System.out.println(a.getpro());
}
That's entirely unrelated to the processor instance you've created in your main method. If your kasir class should logically "know about" the other processor instance, you probably want a processor field in the class, which you might populate via the constructor - so your main method might become:
public static void main(String[] args) {
processor a = new processor();
a.daftarpro();
kasir x = new kasir(a);
x.semua();
}
As an aside, you should really try to follow the Java naming conventions, so classes of Processor and Kasir, and methods of getPro etc. (And if your code actually looks like that in your editor, I suggest you reformat it, too...)

Java synchronization: Synchronization method and synchronization block

I have a mulitThread Java application. In one method, there is a need to synchronize a ArrayList. Since arrayList is not a thread safe, so I have to use synchonization. The problem is that object which is type of ArrayList is not a member variable of the object. Prototype of the method is as follows:
public void simultaneousAccess(ArrayListWrapper aListWrapper){
ArrayList list = aListWrapper.getList();
//...Codes manipulate the list
}
Due to mulitthreading, shall I use
A)
public void synchronized simultaneousAccess(ArrayListWrapper aListWrapper){
ArrayList list = aListWrapper.getList();
//...Codes manipulate the list
}
Or
B)
public void simultaneousAccess(ArrayListWrapper aListWrapper){
ArrayList list = aListWrapper.getList();
Synchronized(list){
//...Codes manipulate the list
}
}
From the performance test, neither works.
But I donot know why?
Here comes whole source codes:
package com.juhani.prototype.sync;
import java.util.ArrayList;
public class ArrayListWrapper {
public ArrayList<Integer> aList = new ArrayList<Integer>();
public ArrayListWrapper(){
Integer one = new Integer(1);
Integer two = new Integer(2);
Integer three = new Integer(3);
aList.add(one);
aList.add(two);
aList.add(three);
}
}
package com.juhani.prototype.sync;
import java.util.ArrayList;
public class TestClass {
public int count_test=0;
public synchronized void test(ArrayListWrapper listWrapper){
ArrayList<Integer> list = listWrapper.aList;
int temp = list.get(1)+1;
list.set(1,temp);
}
public void testBlock(ArrayListWrapper listWrapper){
ArrayList<Integer> list = listWrapper.aList;
synchronized(list){
int temp = list.get(1)+1;
list.set(1,temp);
}
}
}
package com.juhani.prototype.sync;
public class WorkerSyncObj extends Thread {
ArrayListWrapper listWrapper = null;
TestClass tc = null;
int number;
public WorkerSyncObj(int aNumber){
number = aNumber;
}
public void setListWrapper(ArrayListWrapper aListWrapper){
listWrapper = aListWrapper;
}
public void setTestClass(TestClass aTc){
tc = aTc;
}
public void run(){
int i = 1000;
for(int j=0;j<i;j++){
tc.testBlock(listWrapper);
System.out.println("Thread "+number+" is runing at loop "+j+" . index 1 value is:"+listWrapper.aList.get(1));
}
}
}
package com.juhani.prototype.sync.main;
import com.juhani.prototype.sync.ArrayListWrapper;
import com.juhani.prototype.sync.TestClass;
import com.juhani.prototype.sync.WorkerSyncObj;
public class TestMain {
public static void main(String[] args){
ArrayListWrapper list = new ArrayListWrapper();
TestClass tc = new TestClass();
WorkerSyncObj work1 = new WorkerSyncObj(1);
work1.setListWrapper(list);
work1.setTestClass(tc);
WorkerSyncObj work2 = new WorkerSyncObj(2);
work2.setListWrapper(list);
work2.setTestClass(tc);
WorkerSyncObj work3 = new WorkerSyncObj(3);
work3.setListWrapper(list);
work3.setTestClass(tc);
work1.start();
work2.start();
work3.start();
}
}
In the first case you lock on the this object while in the second on the list object. This might be a problem if you call the method from different objects but the list is the same. This is can be the reason of the exception in the first case.
Alternatively you could try some built-in concurrent types like Collections.synchronizedList or CopyOnWriteArrayList.
In java, every object instance has an intrinsic lock (as well as corresponding class itself). Synchronzied keywork is actually use the intrinsic lock for exclusive access, i.e.
syncrhonized method(...) {...}
is equal to
method(...) {
this.intrinsicLock.lock();
...;
this.intrinsicLock.unlock() }
And
synchronized( obj_ref ) { ... }
is equal to
obj_ref.intrinsicLock.lock();
{...}
obj_ref.instrinsicLock.unlock();
So, syncrhonized the method is not right for the protection of list (the parameter). There are two problems if you use the synchronized( list):
1. The granularity of exclusive access seems a little gross
2. Every list access wherever in the whole program need to use "synchronized( list )" too. This is a protocol (for the exclusive acess).
That's the reason why Java library provide quite some concurrent data structures.

Java access a public variable outside a class, SecurityException: MIDlet not constructed by createMIDlet

I'm a newbie in java and I have a small problem. I want to access a variable in one class from another. I have three classes and I want to be able to access a variable in the main class to enable me read the array.
The error I am getting is
java.lang.SecurityException: MIDlet not constructed by createMIDlet
Please see the example below. Please bear in mind they're all in the same package.
package tungPackage;
import com.sun.lwuit.*;
import com.sun.lwuit.animations.CommonTransitions;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import javax.microedition.midlet.MIDlet;
public class TungMidlet extends MIDlet implements ActionListener {
private Command back = new Command("Back");
private Command ok = new Command("Ok");
public ActionListener commandlistListener = new ActionListener() {
public void actionPerformed(ActionEvent cmd) {
// check which command cliked
if (cmd.getCommand() == back) {
// go back to previous form
mainForm.show();
} else if (cmd.getCommand() == ok) {
// go forward
}
}
};
private List list;
private Form mainForm;
private Label promptLabel;
private housesClass houseClassObject = new housesClass();
public int counter; //this is the variable I want to access in a class called calculate class object.
private int sumAmmt;
public TungMidlet tungMidletObject;
public calculateClass calculateClassObject;
public TungMidlet() {
Display.init(this);
}
private ActionListener applistListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if(list.getSelectedIndex()==0){
counter++;
if (counter>5)
{
//check sum price.
sumAmmt = calculateClassObject.calculateSum();
Dialog x = new Dialog("info");
Label label = new Label("Maximum reached.");
Label label2 = new Label("Sum ammt = "+sumAmmt);
x.addComponent(label);
x.addComponent(label2);
x.addCommand(ok);
x.show();
}
else
{
//calculate the price
String info = houseClassObject.randomHouse();
Dialog x = new Dialog("info");
Label label = new Label(info);
x.addComponent(label);
x.addCommand(ok);
x.show();
}
}
}
};
public void startApp() {
//calculateClassObject = new calculateClass();
//sumAmmt = calculateClassObject.calculate(sumAmmt);
mainForm = new Form("Investment Categories");
promptLabel = new Label("choose category");
list = new List();
list.addItem("House");
list.addItem("Cars");
list.addItem("Schools");
list.addItem("Schools");
list.addItem("Supermarkets");
list.addItem("Stocks");
list.addItem("Land");
list.addActionListener(applistListener);
mainForm.addComponent(promptLabel);
mainForm.addComponent(list);
mainForm.addCommand(back);
mainForm.addCommandListener(commandlistListener);
mainForm.setTransitionInAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, true, 1000));
mainForm.show();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void actionPerformed(ActionEvent ae) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
The class I want to access the "counter" variable using is shown below.
package tungPackage;
import java.util.Random;
public class housesClass {
public Random generator = new Random();
public String[] houseArray = new String[5];
public housesClass housesClassObject;
public calculateClass calcobj;// = new calculateClass();
public housesClass()
{
}
public String randomHouse() {
housesClassObject = new housesClass();
houseArray[0] = "Bungalow - 20,000,000 Shillings";
houseArray[1] = "Microhouse - 10,000,000 Shillings";
houseArray[2] = "Flat - 200,000,000 shillings";
houseArray[3] = "Garage apartment - 7,000,000 shillings";
houseArray[4] = "Studio apartment - 13,000,000 shillings";
int rnd = generator.nextInt(houseArray.length);
housesClassObject.housePrices(rnd);///noma
String house = houseArray[rnd];
return house;
}
void housePrices(int houseNumber) {
calcobj = new calculateClass();
TungMidlet tungmidobj = new TungMidlet();
int counter = tungmidobj.counter;
int[] housePriceArray = new int[5];
housePriceArray[0] = 20000000;
housePriceArray[1] = 10000000;
housePriceArray[2] = 200000000;
housePriceArray[3] = 7000000;
housePriceArray[4] = 13000000;
int price = housePriceArray[houseNumber];
calcobj.storePrice(counter,price);
}
}
The other supporting class is shown below.
package tungPackage;
public class calculateClass {
int[] storeArray = new int[5];
public calculateClass()
{
}
public void storePrice(int counter, int number2)
{
storeArray[counter] = number2;
}
public int calculateSum()
{
int sum =0;
for(int i=1; i<6; i++){
sum= sum+storeArray[i];
}
return sum;
}
}
Are you getting an error? It looks like your access code should work.
I can't seem to find anywhere that you actually initialise counter though, so maybe your problem is that you need to put counter = 0; somewhere in your code.
Java is also object oriented so you should avoid accessing like the above and make some 'getter and setter' methods:
public int getCounter() {
return counter;
}
and then call int counter = tungmidobj.getCounter();
remove TungMidlet constructor. If there was something useful to do there, you could also declare it protected - but this is not the case with your code snippet, see below.
Wherever you try to invoke that constructor directly, remove code that does this and find another way to do what you need. If needed, study code examples provided in LWUIT Tutorial - Introduction for how typical things are done in LWUIT.
put statement Display.init() in the beginning of the startApp method,
just like it is done in LWUIT Tutorial - Hello, LWUIT! example code
The reason why you are getting SecurityException is because you invoke TungMidlet constructor directly. Don't do that.
MIDP API documentation for MIDlet constructor states:
Throws:
SecurityException - unless the application management software is creating the MIDlet.
one way is
TungMidlet tungMidlet=new TungMidlet();
System.out.println(tungMidlet.counter);
but know encapsulation
second way is
you can make counter private variable and provide setter and getters.
private int counter;
public void setCounter(int counter){
this.counter=counter;
}
public int getCounter(){
return counter;
}
second way is preferred way as it achieves encapsulation

Categories

Resources