I'm creating a method to send and receive data from arduino . After I call this method in a thread. I use ThreadPoolExecutor to execute this thread 3 times.Because I have 3 JtestField and I need in every one show a received data. when I execute them only one which ise shown. I was trying to use differe t methods to synchronize these threads but no result. Thank you for your help.
This is the method:
synchronized void sendReceive(String txt,JTextField txt_){
PrintWriter output = new PrintWriter(OpenPort.getPort().getOutputStream());
cr=txt;
output.print(cr);
output.flush();
OpenPort.getPort().addDataListener(new SerialPortDataListener() {
#Override
public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; }
#Override
public void serialEvent(SerialPortEvent event)
{
Scanner data=new Scanner(OpenPort.getPort().getInputStream());
while(data.hasNextLine()) {
String msg = null;
Object item=null;
try{msg= data.nextLine();}catch(Exception e){}
if(msg != null) {
txt_.setText(msg);
list.add(msg);
System.out.println(list);
System.out.println(item);
}
msg = null;
}
}
});
}
The thread in which I call it:
class ThreadDemo extends Thread {
String cr=null;
JTextField txt_;
String txt;
private Thread t;
ThreadDemo(String txt,JTextField txt_) {
this.txt = txt;
this.txt_ = txt_;
}
#Override
public void run() {
sendReceive(txt,txt_);
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
}
and after I use the ThreadPoolExecutor to execte threads in the constructor of my first class:
//ip
executor.execute(new ThreadDemo("ee_get:100",SCAN.ipAddress_txt));
//port
executor.execute(new ThreadDemo("ee_get:160",SCAN.port_txt));
//intervale
executor.execute(new ThreadDemo("ee_get:60",SCAN.intervale_txt));
executor.shutdown();
please any help I was spending a lot of time to resolve this problem and no result.
Normally I must send 3 commands to arduino and receive 3 times data and every time this data must be shown in a JTextField. However I see one received data in the JTextfield
Related
im making a networked game that has a server which creates a clientHandler thread every time a client joins. I want to ask the first client that joined if it wants to start the game every time a new client joins, giving it the current number of players connected. Writting through the clientHandlers printwritter gives a nullPointerException, even though ive started the thread before doing this. what could be the problem?
Here is the server code:
`public class Server implements Runnable{
private ArrayList<ClientHandler> handlers = new ArrayList<>();
private ArrayList<Player> players = new ArrayList<>();
private Game game;
private boolean start;
public static void main(String[] args) {
Server server = new Server();
Thread s = new Thread(server);
s.start();
}
public void login(String name){
//todo
for (ClientHandler c : handlers){
if (c.getName().equals(name)){
alreadyTaken(name);//todo
}
else{
players.add(new HumanPlayer(name,c));//todo
}
}
}
public void setStart(){
start = true;
}
private void alreadyTaken(String name) {
}
public void setTurn(ServerHandler sh){
//todo
}
public void updateView(){
}
public String hello() {
return "Hello"; //?
}
public void place(String s){
}
#Override
public void run() {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(1800);
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("----Server----");
while (!serverSocket.isClosed()) {
try {
Socket socket = serverSocket.accept();
ClientHandler handler = new ClientHandler(socket,handlers,this);
handlers.add(handler);
Thread h = new Thread(handler);
h.start();
System.out.println("A new client has connected");
System.out.println(handlers.get(0));
handlers.get(0).out.println("START? "+ handlers.size());
if (start){
System.out.println("start request works");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
`
And here's the client handler code:
`public class ClientHandler implements Runnable{
private Socket socket;
private ArrayList<ClientHandler> handlers;
private Server server;
public PrintWriter out;
private BufferedReader in;
private String name;
public ClientHandler(Socket socket, ArrayList<ClientHandler> handlers, Server server){
this.socket = socket;
this.handlers = handlers;
this.server = server;
}
public void broadcastMessage(String msg){
System.out.println("Broadcasting");
for (ClientHandler s : this.handlers){
s.out.println("Player: " + msg);
}
}
public static String removePrefix(String s, String prefix)
{
if (s != null && s.startsWith(prefix)) {
return s.split(prefix, 2)[1];
}
return s;
}
public String getName(){
return name;
}
#Override
public void run() {
try {
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
new Thread(() -> {
while(socket.isConnected()){
String msg;
try {
msg = in.readLine();
while(msg!=null){
switch (msg.split(" ")[0]){
case "LOGIN":
name = removePrefix(msg,"LOGIN ");
server.login(name);//todo
break;
case "HELLO":
server.hello();//todo
break;
case "PLACE":
server.place(removePrefix(msg,"PLACE "));
break;
case "QUIT":
//todo
break;
case "STOP":
//todo
break;
case "START":
server.setStart();
default:
broadcastMessage(msg);
break;
}
msg = in.readLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}`
I tried making a method in the client handler class which does the same thing. The server would just call that instead of writting directing through the PrintWriter, but i got the same error.
Starting a thread does not mean it is guaranteed to actually finish executing the first statement in its run() method before start() returns. In fact,
Usually it won't - starting a thread takes some time, and start() returns as soon as it can.
A JVM that runs a few statements in the thread you just started before start() returns is 'correct' - that is fine. A JVM that doesn't is also fine. Generally you don't want threads, because nothing is predictable anymore. At the very least you want to keep 'inter-thread comms' down to a minimum. Anytime a single field is used from more than one thread, things get very tricky.
What you need is synchronized or other tools to insert predictability in this code.
First, fix a bug
Your ClientHandler's run() code starts another thread for no reason. Take all that out, your run() method in ClientHandler should set up out and in and then immediately do while (socket.isConnected())
Synchronizing
At the very basic level, make a locker object and use notify/wait:
private final Object lock = new Object();
#Override public void run() {
try {
synchronized (lock) {
out = ...;
in = ...;
lock.notifyAll();
}
while (socket.isConnected()) { ... }
out definitely cannot be public here, you can't refer to a stream from multiple threads and expect things to work out!
Just 'fixing' your code involves then using something like:
public OutputStream getOutputStream() {
synchronized (lock) {
while (out == null) {
lock.wait();
}
}
return out;
}
Which will ensure that any thread that wants the out will wait for the other thread to get far enough, but, really, this is just setting you up for another 20 threading problems down the line. Instead, you want one object responsibile for all communication (both outgoing and incoming), and a concurrency-capable queue (there are various collections in the java.util.concurrent package good for this). Then:
Any other threads that want to just send data dump their message in the queue.
You have either 1 thread doing all comms, or 2 (one doing incoming, and one doing outgoing), both dedicated. The outgoing one just loops forever, grabbing objects from the queue and sending them.
If a thread wants to send a message and wait for the response, you need to use .wait() or nicer API from e.g. java.util.concurrent, or, use callback hell - you pass a closure with the code to run once the result is received.
I want login multiple accounts so that's why i am using threads..its working fine sometimes but sometimes same account logged multiple times instead of remaining accounts...any one give suggestions please.
gmail_synclist=new CopyOnWriteArrayList<>();
gmail_synclist.clear();
gmail_synclist = Helpers.getArrayList(WelcomeMessage.this, "email_creds");
List<Thread> threads = new ArrayList<Thread>();
for( int i = 0; i < gmail_creds.size(); i++){
final int j = i;
Thread t = new Thread(new Runnable() {
public void run(){
synchronized (gmail_synclist) {
Helpers.sharedPreferencess(WelcomeMessage.this,"userEmail", gmail_creds.get(j).userEmail);
Helpers.sharedPreferencess(WelcomeMessage.this,"userPassword",gmail_creds.get(j).userPassword);
AccountSetupBasics.actionNewAccount(WelcomeMessage.this);
}
}
})
t.start();
threads.add(t);
}
// Let all threads to finish execution prior continuing main thread.
try {
for(Threat t: threads){
t.join();
}
} catch(InterruptedException ie){
ie.printStackTrace();
}
alright, but not properly formatted, I will show b/w frag and handler thread
// A simple handler thread clas
public class MyHandlerThread extends HandlerThread {
private final static String TAG_THREAD = MyHandlerThread.class.getSimpleName();
public MyHandlerThread() {
super("MyHandlerThread");
Log.e(TAG_THREAD, " ctor ");
}
}
// a dummy fragment
private MyHandlerThread myHandlerThread;
public Handler mWorkerHandler;
int MSG_ONE;
int MSG_TWO;
#Override
public void onViewCreated(whatever) {
// start the thread
threadOperation();
// send a message
sendMessage(MSG_ONE)
}
private void threadOperation() {
System.out.println("tread started");
myHandlerThread = new MyHandlerThread();
myHandlerThread.start();
Looper looper = myHandlerThread.getLooper();
mWorkerHandler = new Handler(looper, new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
if(msg.what == MSG_ONE){
// do your work based on that
// these are all in bankground thread, so any ui updation task
// use runOnUiTHread() or main thread handler to post task
}
else if(msg.what == MSG_TWO){
// do work based on two
}
return true;
}
});
}
public void sendMessage(int whatMsg) {
System.out.println("send message --------------------");
doSimulation();
Message message = mWorkerHandler.obtainMessage(whatMsg);
mWorkerHandler.sendMessage(message);
Log.e(TAG, "message sent ..");
}
everybody.
Hope you can help me with this one:
I have two threads, which are tasked with handling connections from a client.
This is my code
ServerSocket loginSocket = new ServerSocket(8000);
ServerSocket fileSocket = new ServerSocket(7000);
while (running) {
new LoginThread(loginSocket.accept(),loginInormation).start();
new LoaderThread(fileSocket.accept()).start();
}
When I try to connect to the loginSocket two times, the server will block and stop working, blocking the client, but this doesn't happen if I delete this:
new LoginThread(loginSocket.accept(),loginInormation).start();
I'm not getting any error messages, so why is this happening and how can I fix this?
The accept() method is a blocking method, which means that your program won't continue until a connection is made with loginSocket().
When you're creating your LoginThread, the program waits a connection to set the first parameter of your object, and it will not continue the execution until a connection is made.
The line new LoginThread(loginSocket.accept(),loginInormation).start(); contains the method call loginSocket.accept(), which will be called before this thread is created. This method call will block until a client logs in. (In addition, the second thread will be blocked by fileSocket.accept()).
As for a solution, I would move the accept() calls to inside each of the Threads. You will need to pass the sockets to the threads for them to do this.
Start fileSocket and login socket in different threads
package com.ca.training.task.app;
import java.io.IOException;
import java.net.ServerSocket;
public class App {
public void execute() {
LoginRunnable loginRunnable = new LoginRunnable();
loginRunnable.setLoginInformation(new Object());//Login information
FileRunnable fileRunnable = new FileRunnable();//Data for loaded runnable.
fileRunnable.setParams(new Object());
startLoginThread(loginRunnable);
startFileThread(fileRunnable);
}
private static void startLoginThread(LoginRunnable loginRunnable) {
Thread loginThread = new Thread(loginRunnable);
loginThread.start();
}
private static void startFileThread(FileRunnable fileRunnable) {
Thread loadedThread = new Thread(fileRunnable);
loadedThread.start();
}
class LoginRunnable implements Runnable {
private Object loginInformation;
#Override
public void run() {
try {
ServerSocket loginSocket = new ServerSocket(8000);
loginSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getLoginInformation() {
return loginInformation;
}
public void setLoginInformation(Object loginInformation) {
this.loginInformation = loginInformation;
}
}
class FileRunnable implements Runnable {
private Object params;
#Override
public void run() {
try {
ServerSocket fileSocket = new ServerSocket(7000);
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getParams() {
return params;
}
public void setParams(Object params) {
this.params = params;
}
}
}
Following is some parts of my code, which uses Threading. The purpose is to retrieve all the records from database (approx. 5,00,000) and send them alert email messages. The problem I am facing is the variable emailRecords becomes very heavy and too much time is taken to send email message. How can I make it fast by using multi-threading such that 5,00,000 records are processed parallelly? I tried to use ExecutorService but got confused in implementing it. I got mixed up in the method checkName(), getRecords() and sendAlert(). All these 3 methods are used relevantly. So, where to use executorService ??
Please provide me the suggestion how to proceed with the following code and which part needs editing? Thanks in advance!!
public class sampledaemon implements Runnable {
private static List<String[]> emailRecords = new ArrayList<String[]>();
public static void main(String[] args) {
if (args.length != 1) {
return;
}
countryName = args[0];
try {
Thread t = null;
sampledaemon daemon = new sampledaemon();
t = new Thread(daemon);
t.start();
} catch (Exception e) {
e.printStackTrace()
}
}
public void run() {
Thread thisThread = Thread.currentThread();
try {
while (true) {
checkName(countryName);
Thread.sleep(TimeUnit.SECONDS.toMillis(10));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void checkName(String countryName) throws Exception {
Country country = CountryPojo.getDetails(countryName)
if (country != null) {
getRecords(countryconnection);
}
}
private void getRecords(Country country, Connection con) {
String users[] = null;
while (rs.next()) {
users = new String[2];
users[0] = rs.getString("userid");
users[1] = rs.getString("emailAddress");
emailRecords.add(props);
if (emailRecords.size() > 0) {
sendAlert(date, con);
}
}
}
void sendAlert(String date, Connection con) {
for (int k = 0; k < emailRecords.size(); k++) {
//check the emailRecords and send email
}
}
}
From what i can tell is that you would most likely be single threaded data retrieval, and multi-threaded for the e-mail sending. Roughly, you'd be cycling through your result set and building a list of records. When that list hits a certain size, you make a copy and send off that copy to be processed in a thread, and clear the original list. At the end of the result set, check to see if you have unprocessed records in your list, and send that to the pool as well.
Finally, wait for the threadpool to finish processing all records.
Something along these lines:
protected void processRecords(String countryName) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.CallerRunsPolicy());
List<String[]> emaillist = new ArrayList<String>(1000);
ResultSet rs = ....
try {
while (rs.next()) {
String user[] = new String[2];
users[0] = rs.getString("userid");
users[1] = rs.getString("emailAddress");
emaillist.add(user);
if (emaillist.size() == 1000) {
final List<String[]> elist = new ArrayList<String[]>(emaillist);
executor.execute(new Runnable() {
public void run() {
sendMail(elist);
}
}
emaillist.clear();
}
}
}
finally {
DbUtils.close(rs);
}
if (! emaillist.isEmpty()) {
final List<String[]> elist = emaillist;
executor.execute(new Runnable() {
public void run() {
sendMail(elist);
}
}
emaillist.clear();
}
// wait for all the e-mails to finish.
while (! executor.isTerminated()) {
executor.shutdown();
executor.awaitTermination(10, TimeUnit.DAYS);
}
}
The advantage of using the FixedThreadPool is that you don't have to do the expensive process of creating the threads again and again, its done at the beginning...see below..
ExecutorService executor = Executors.newFixedThreadPool(100);
ArrayList<String> arList = Here your Email addresses from DB will go in ;
for(String s : arList){
executor.execute(new EmailAlert(s));
}
public class EmailAlert implements Runnable{
String addr;
public EmailAlert(String eAddr){
this.addr = eAddr;
}
public void run(){
// Do the process of sending the email here..
}
}
Creating a second thread to do all of the work in instead of doing the same work in the main thread isn't going to help you avoid the problem of filling up the emailRecords list with 5 million records before processing any of them.
It sounds like your goal is to be able to read from the database and send email in parallel. Instead of worrying about the code, first think of an algorithm for the work you want to accomplish. Something like this:
In one thread, query for the records from the database, and for each result, add one job to an ExecutorService
That job sends email to one person/address/record.
or alternatively
Read records from the database in batches of N (50, 100, 1000, etc)
Submit each batch to the executorService
Im facing one problem in streaming data capture for reading the broadcast data during multithreading, pls help or suggest,
Actually there is one class which is reading data from one of the udp socket. Another class accepts the tcp connection from every client request, creates a thread for every client and request the same udp class for data. The thing is working with 1st thread which gets created. But when i request with another client from another pc/ip the packets get losted to the 2nd client/thread
I have made a workaround by creating a list where im storing the Threads outputstream object
and looping it to send the data to all the client. But this is just temporary as it ll delay the packets if clients/connections gets increased.
code for reading UDP Data
public class EventNotifier
{
private InterestingEvent ie;
public DatagramSocket clientSocket;
public String[] split_str;
byte[] receiveData;
HashMap<String, String> secMap = new HashMap<String, String>();
public EventNotifier(InterestingEvent event)
{
ie = event;
clientSocket = new DatagramSocket(9050);
receiveData = new byte[500];
}
public String getDataFeed(String client_id)
{
try
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String s = new String(receivePacket.getData());
String split_str = s.split(",");
if(secMap.containsValue(split_str[0]))
return s;
else
return "";
} catch(Exception e3) {}
}
}// end of eventNotifier class
code for multithreading handling client requests
public class multiServer
{
static protected List<PrintWriter> writers = new ArrayList<PrintWriter>();
static String client_id = "";
public static void main(String[] args)
{
try
{
ServerSocket servsock = new ServerSocket(8858);
Socket incoming;
while(true)
{
incoming = servsock.accept();
multiServerThread connection = new multiServerThread(incoming);
Thread t1 = new Thread(connection);
t1.start();
}
}
catch(IOException e)
{
System.out.println("couldnt make socket");
}
}
}
class multiServerThread extends Thread implements InterestingEvent
{
Socket incoming;
PrintWriter out=null;
PrintWriter broad=null;
BufferedReader in = null;
String cliString=null;
private EventNotifier en;
int id;
public static String udp_data;
public void interestingEvent(String str1)
{
this.udp_data = str1;
}
public String getUdpData()
{
String _udp_data = this.udp_data;
return _udp_data;
}
multiServerThread(Socket incoming)
{
this.incoming=incoming;
en = new EventNotifier(this);
}
public void run()
{
try
{
out = new PrintWriter(incoming.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
cliString = in.readLine();
multiServer.writers.add(out);
while(true)
{
try
{
udp_data = en.getDataFeed(cliString);
if(udp_data!=null && udp_data.length()>0)
{
//workaround for serving the data to all cleints who are connected
for (int i=0; i<multiServer.writers.size();i++)
{
broad=multiServer.writers.get(i);
broad.println(udp_data.trim());
}
//else will directly write to the outputstream object for every thread which is connected
// out.println(udp_data.trim());
}
}
catch (Exception e)
{
System.out.println("exception "+e);
}
Thread.sleep(1);
}
} catch(IOException e)
{
System.out.print("IO Exception :: "+ e);
}
catch(InterruptedException e)
{
System.out.print("exception "+ e);
}
}
}
You need mutual exclusion (or a different design).
For example, what will happen if two threads call multiServer.writers.add(out); concurrently?
From the ArrayList Javadocs
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or [...])
Another problem is two calling udp_data = en.getDataFeed(cliString); concurrently. The second thread might overwrite the result of the first. You'll loose data!
What happens if one thread calls for (int i=0; i<multiServer.writers.size();i++) while another thread is busy doing multiServer.writers.add(out);? The size may have increased, before out has actually been added to the list!
public class multiServer
{
private List<PrintWriter> writers = new ArrayList<PrintWriter>();
public synchronized void addWriter(PrintWrite out) {
writers.add(out);
}
public synchronized void serveAllWriters(String data) {
for (int i=0; i<multiServer.writers.size();i++)
{
broad=multiServer.writers.get(i);
broad.println(data);
}
}
}
Now when a thread tries to add a writer, the synchronizeds will make sure no other thread is adding or printing. So multiServerThread should be fixed to use the new methods:
class multiServerThread extends Thread implements InterestingEvent
{
//...
private String udp_data;
//...
myMultiServer.addWriter(out);
//...
udp_data = en.getDataFeed(cliString);
if(udp_data!=null && udp_data.length()>0)
myMultiServer.serveAllWriters(udp_data.trim());
//...
}
There might be more problems, not sure I don't fully understand your code. The question you must ask yourself is, can another thread read and/or write the same data or object? Yes? Then you'll need proper synchronization.