B4J Question Multiple Threads accessing a Global list

Jmu5667

Well-Known Member
Licensed User
Longtime User
Hi

Is it ok for multiple threads (socket connections - Android apps) to update a global list, adding new entries, and another thread removing them as they are being forwarded to a windows back office system via another socket connection.

My concern is they may be locking issues on the global list.

Regards

John.
 

Jmu5667

Well-Known Member
Licensed User
Longtime User
I have a socket class, and when each B4A connection requested is accepted I create a class instance for that and add it to my connections list in the main app thread. I can see the threads being created using windows resource manager. Maybe a diagram would help explain it ???
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
upload_2014-9-26_15-50-2.png

The Blue are android apps, the green is B4J, the red is our current back office system. The red lines indicate a CLASS adding a message to the list, the blue line indicates a removal from the list.

I would like to know if this method has the potential to cause a lock problem on the list.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
AsyncStreams are used for socket comms, are you suggesting AsyncStreams between the Class's and the main thread to add to the list ?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
AsyncStreams are used for socket comms, are you suggesting AsyncStreams between the Class's and the main thread to add to the list ?
No.

The threads that you see in task manager are related to AsyncStreams. The events are running in the main thread, so you don't need to worry about any threading issues.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
No.

The threads that you see in task manager are related to AsyncStreams. The events are running in the main thread, so you don't need to worry about any threading issues.

Hi Erel

I was wondering in B4J when I create an instance of a class (the sockets class), how can I get it it run on it own thread ?

Regards

John.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
You need to use AsyncStreams for that. The communication will happen with the help of two background threads.

Hi Erel

Thanks for the reply. I am currently using AsyncStreams in the client socket. I guess the I am concerned about max number of clients that will connect. The main module has the serversocket and listens for new connections. In the main module I have a list and store each new connection.

B4X:
   ' // client socket connection
   Type mSocketConnection(index     As Long, _
              inUse     As Boolean, _
              public_id     As String, _
            buffer_in     As List, _
            buffer_out    As List, _
              messages_in    As List, _
              sck     As class_socket, _
              profile       As mUserProfile, _
              RT       As mSocketConnectionRT _
               )

Private Sub srvListener_NewConnection(Successful As Boolean, NewSocket As Socket)
   
   
   Dim x As Long
   Dim ExistingClient As mSocketConnection
   Dim NewClient As mSocketConnection
   
   Dim freeSocket As Long
   
   'srvListener.Close
   
   Log(DateTime.Time(DateTime.Now) & " - srvListener_NewConnection (" & Successful & ") " & NewSocket.RemoteAddress)
   If Successful Then
     freeSocket = -1
     For x = 0 To connections.Size - 1
       ExistingClient = connections.get(x)
       If Not(ExistingClient.InUse) Then
         freeSocket = x
         x = (connections.Size+1)
       End If
     Next
     
     If freeSocket = -1 Then
       ' // add to the list
       connections.Add(NewClient)
       ' // pointer to new list entry
       freeSocket = (connections.Size-1)
       Log(DateTime.Time(DateTime.Now) & " - srvListener_NewConnection (NEW) " & freeSocket)
       ' // initialise client connection
       NewClient.Initialize
       NewClient.sck.Initialize(Me, "Client", freeSocket)
       ' // initialise the user profile
       NewClient.profile.Initialize  
       NewClient.profile.RESPONDER.Initialize  
       NewClient.profile.RESPONDER.Initialize
       NewClient.profile.HW_SWITCH.Initialize
       NewClient.profile.HW_LOC.Initialize
       NewClient.profile.TEST_PROC.Initialize
       ' //assign it
       ExistingClient = NewClient
     Else
       Log(DateTime.Time(DateTime.Now) & " - srvListener_NewConnection (EXISTING) " & freeSocket)
     End If
     ' // flag this as being used
     ExistingClient.inUse = True
     ' // this client object is either a new/ or recycled one
     ExistingClient.sck.NewConnection(NewSocket)
   Else
     Log("Connection attempt failed: " & LastException.Message)
   End If
   
   srvListener.Listen
   
   
   
End Sub

So, I guess that class_socket in the mSocketConnection runs in the main thread. What I would like to do is have this running in its own thread so as not to overload the main thread.

I hope I have explained myself, and is it possible to do this in b4j.

Many thanks

John.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can use the Threading library to run it on another thread. However it will only cause problems.

This code will be executed once per each new connection. Unless I'm missing something it will happen very fast and will not block the main thread.

If you wish to implement a high performance server then you need to use the server library instead of handling the sockets yourself. It will be simpler and will perform better.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
You can use the Threading library to run it on another thread. However it will only cause problems.

This code will be executed once per each new connection. Unless I'm missing something it will happen very fast and will not block the main thread.

If you wish to implement a high performance server then you need to use the server library instead of handling the sockets yourself. It will be simpler and will perform better.

By Server library are you referring to jServer(2.03) on the main thread, if so, that is what I use to listen.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
Yes, jServer. However I don't see that you are using it. jServer works with servlet handlers.

The server threads are explained here: http://www.b4x.com/android/forum/threads/server-building-web-servers-with-b4j.37172/#content

However with jServer you are implementing a HTTP server not a custom server.

Hi Erel

Is is possible, now or in the future to have a jServerCustom library, where we can build multi-threaded servers apps without using the HTTP protocol.

Regards
John.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
Hi Erel

I guess if you were to modify the lib so it could be flagged as CUSTOM or HTTP. For custom none of the HTTP stuff would be relevant. It would listen for connections and add them to the connects map.

A servlet handler would be created and allow a class to be assigned to it so it can handle all data from the client connection to the server. Standard socket methods I would think should be sufficient.

The connections map should have a custom_id field which the servlet can assign to it, and the map should be able to searched (I will expand on this for you)

On feature would be that the server thread can post data to a servlet and receive data from a servlet. This would allow the main thread operate as a router of packets.

I would be more then happy to write a more detailed explanation for you and work on this together if you have time.

Regards

John.
 
Upvote 0
Top