I need a barrier in my multi-thread project on Linux. I know the pthread_barrier_init() and pthread_barrier_wait(), but I want to run my project on android. It didn't have these functions. I know how to implement it with atomic add and atomic comparison. I want to use a semaphore, can I use a semaphore to implement it?
Use a CyclicBarrier, this is more or less identical to a pthread barrier.
Sample code (from linked page)
class Solver {
final int N;
final float[][] data;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) { myRow = row; }
public void run() {
while (!done()) {
processRow(myRow);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
barrier = new CyclicBarrier(N,
new Runnable() {
public void run() {
mergeRows(...);
}
});
for (int i = 0; i < N; ++i)
new Thread(new Worker(i)).start();
waitUntilDone();
}
}
Related
I'm using android socket.io but the problem is that emit event runs twice instead of once , i mean that i wrote just one emit code in the onCreate method , but it sends two request for the server ?
I searched alot but not found anything .
I use node js in the backend ,and my code has not any problems .
Is there a bug in socket.io for android ?
Here is my code :
SocketManager.getInstance().connect();
// Creating Bids
final Handler mHandler04 = new Handler(Looper.getMainLooper());
mHandler04.post(new Runnable() {
#Override
public void run() {
SocketManager.getInstance().getSocket().emit("allc", "some");
SocketManager.getInstance().getSocket().on("allcRes", new Emitter.Listener() {
#Override
public void call(final Object... args) {
g.context.runOnUiThread(new Runnable() {
#Override
public void run() {
JSONArray jsonArray = (JSONArray) args[0];
arrayComps.clear();
Log.d(TAG, "run: " + jsonArray);
try {
for (int i = 0; i < jsonArray.length(); i++) {
createView(jsonArray.getJSONObject(i).getString("title"), jsonArray.getJSONObject(i).getString("realprice"), jsonArray.getJSONObject(i).getString("id"), jsonArray.getJSONObject(i).getString("starttime"), jsonArray.getJSONObject(i).getString("img"));
CustomViewCompetition css = (CustomViewCompetition) LinearLayoutItemHolder.getChildAt(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
});
}
});
final Handler bidsupdateHandler = new Handler(Looper.getMainLooper());
bidsupdateHandler.post(new Runnable() {
#Override
public void run() {
SocketManager.getInstance().getSocket().on("bidsupdate", new Emitter.Listener() {
#Override
public void call(final Object... args) {
final JSONArray jsonArray = (JSONArray) args[0];
g.context.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d(TAG, "run in bidsupdate");
try {
for (int i = 0; i < jsonArray.length(); i++) {
bidsMap.put(jsonArray.getJSONObject(i).getInt("key"), jsonArray.getJSONObject(i).getInt("value"));
}
for (int i = 0; i < LinearLayoutItemHolder.getChildCount(); i++) {
CustomViewCompetition cs = (CustomViewCompetition) LinearLayoutItemHolder.getChildAt(i);
Log.d(TAG, "run in cs " + cs.txtCsRealPrice.getText());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
});
}
});
the Problem is when i get the cs.txtCsTitle.getText() it is just showing me one of them
Add this line:
SocketManager.getInstance().getSocket().emit("allc", "some");
just after:
SocketManager.getInstance().connect();
So your code will be like
SocketManager.getInstance().connect();
SocketManager.getInstance().getSocket().emit("allc", "some");
And remove from where you are already using in handler. Also you dont need handlers why you are using handlers? Create your listener and emit your subscription out of handlers it needs to be created or subscribed once. On creation of emitter listener pass views if you need to update any view. then update the views here you may need runnable to update UI on uiThread.
Create Class as follows:
public class YourListener implements Emitter.Listener
{
private yourView view;
public YourListener (View view)
{
this.view = view;
}
#Override
public void call(Object... args)
{
// do your work here
}
}
and replace below code :
SocketManager.getInstance().getSocket().on("allcRes", new Emitter.Listener() {
#Override
public void call(final Object... args) {
g.context.runOnUiThread(new Runnable() {
#Override
public void run() {
JSONArray jsonArray = (JSONArray) args[0];
arrayComps.clear();
Log.d(TAG, "run: " + jsonArray);
try {
for (int i = 0; i < jsonArray.length(); i++) {
createView(jsonArray.getJSONObject(i).getString("title"), jsonArray.getJSONObject(i).getString("realprice"), jsonArray.getJSONObject(i).getString("id"), jsonArray.getJSONObject(i).getString("starttime"), jsonArray.getJSONObject(i).getString("img"));
CustomViewCompetition css = (CustomViewCompetition) LinearLayoutItemHolder.getChildAt(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
});
with:
SocketManager.getInstance().getSocket().on("your_subscription", new YourListener (yourView));
I am replacing my Sqlite database with an online database (Firestore). For that each answer of the database comes back to me by callback.
The problem is that I have several calls to the database in a loop that filled a table and that the table is not accesible unless I declare it in the end and therefore I can not change it.
So I'm looking for a way to fill this table without completely modifying the code that already exists. I saw the ArrayBlockingQueue but I wonder if a simpler solution does not exist.
If possible I would like to keep all the variables inside the function but I have not yet found a solution for that.
I know that for this example we do not necessarily need a table but I want to keep it because it's just an example ;)
Before (SQLite)
public int player_in_x_game(int id_player) {
int gamesWherePlayerIsHere = 0;
ArrayList<Games> gamesArray = Database.getGamesArray();
for (Game game: gamesArray)
if(Utils.isPlayerPresentInGame(game.getId(), idPlayer))
gamesWherePlayerIsHere++;
return gamesWherePlayerIsHere;
}
After (with callbacks)
private static int counter= 0;
private static int resultNP = 0;
private static ArrayBlockingQueue<Integer> results;
public static void numberGamesWherePlayerIsPresent(final long idPlayer, final Callbacks.IntCallback callback){
Thread thread = new Thread() {
#Override
public void run() {
games(new Callbacks.ListGameCallback() {
#Override
public void onCallback(ArrayList<Game> gameArrayList) {
counterNumberGamesWherePlayerIsPresent= gameArrayList.size();
results = new ArrayBlockingQueue<>(gameArrayList.size());
for (Game game: gameArrayList){
Utils.isPlayerPresentInGame(game.getId(), idPlayer, new Callbacks.BooleanCallback() {
#Override
public void onCallback(boolean bool) {
if (bool)
results.add(1);
else
results.add(0);
}
});
}
int result;
try {
while (counter > 0) {
result = results.take();
counter--;
resultNP += result;
}
}catch (InterruptedException ie){
ie.fillInStackTrace();
Log.e(TAG,"results.take() failed");
}
callback.onCallback(resultNP);
}
});
}
};
thread.setName("Firestore - numberGamesWherePlayerIsPresent()");
thread.start();
}
So the thing is that i want to get Bitmap from absolute path, so i pass those paths as ArrayList<Strings> to my presenter, where i have next piece of code:
private void decodeImageUri(final ArrayList<String> imageUris) {
while(imageCounter < imageUris.size()) {
DecodeBitmapsThreadPool.post(new Runnable() {
#Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeFile(imageUris.get(imageCounter));
mImagesBase64Array.add(bitmapToBase64(bitmap));
}
});
}
DecodeBitmapsThreadPool.finish();
Log.d("SIZE OF BASE64", " ---------- " + mImagesBase64Array.size());
}
And this is my ThreadPool class:
public class DecodeBitmapsThreadPool {
private static DecodeBitmapsThreadPool mInstance;
private ThreadPoolExecutor mThreadPoolExec;
private static int MAX_POOL_SIZE;
private static final int KEEP_ALIVE = 10;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
public static synchronized void post(Runnable runnable) {
if (mInstance == null) {
mInstance = new DecodeBitmapsThreadPool();
}
mInstance.mThreadPoolExec.execute(runnable);
}
private DecodeBitmapsThreadPool() {
int coreNum = Runtime.getRuntime().availableProcessors();
MAX_POOL_SIZE = coreNum * 2;
mThreadPoolExec = new ThreadPoolExecutor(
coreNum,
MAX_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
workQueue);
}
public static void finish() {
mInstance.mThreadPoolExec.shutdown();
}
}
So when i start ThreadPool it looks like it get in some kind of a endless loop (according to Logcat) and then i just get OutOfMemoryException. I wonder what i`m i doing wrong, since i cant debug it. I simply want to decode the bitmap in background threads and create base64 representation of those Bitmaps, so i can upload them to the server. P.S. Any ideas how can this be implemented with RxJava2? Thanks in advance!
You are not incrementing imageCounter, so it actually is an endless loop.
An enhanced for loop is less error prone:
for (String uri : imageUris) {
...
Bitmap bitmap = BitmapFactory.decodeFile(uri);
...
imageCounter value not changed in while loop,so this condition (imageCounter < imageUris.size()) always true and while loop run infinite times
while(imageCounter < imageUris.size()) {
DecodeBitmapsThreadPool.post(new Runnable() {
#Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeFile(imageUris.get(imageCounter));
mImagesBase64Array.add(bitmapToBase64(bitmap));
}
});
}
The issue is that you don't increment the while loop, so the while loop's condition will never be met. You should increment it at the end of code within the while loop like so:
while(imageCounter < imageUris.size()) {
DecodeBitmapsThreadPool.post(new Runnable() {
#Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeFile(imageUris.get(imageCounter));
mImagesBase64Array.add(bitmapToBase64(bitmap));
}
});
imageCounter++;
}
Though as mentioned in bwt's answer, an enhanced for loop is generally the best approach for these types of tasks.
I have three strings
String one="Connecting.";
String two="Connecting..";
String three="Connecting...";
I have a textView, what I want is to set text to textview in this order..
one-->two-->three-->one-->two-->three and so on until the process is completed.
I have done it in a for loop based on value i.e
if(value%3==0){
tx.setText(one);
}
else if(value%3==1){
tx.setText(two);
}
else
{
tx.setText(three);
}
This is done inside a thread and it is working well.
But I dont want to rely on "value".. I jst want that until process is completed the text changes in order as mentioned above.
I know it is vague but I am not getting how to do this.
Please if someone can give any hint.
code:
public void startProgress(View view) {
bar.setProgress(0);
tx.setText("Connect");
new Thread(new Task()).start();
}
class Task implements Runnable {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
final int value = i;
try {
Thread.sleep(500);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
bar.setProgress(value);
String one="Connecting.";
String two="Connecting..";
String three="Connecting...";
if(value%3==0){
tx.setText(one);
}
else if(value%3==1){
tx.setText(two);
}
else
{
tx.setText(three);
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
It makes sense to have a counter like value that keeps incrementing. But you could do it a little more simply:
String[] texts = new String[3] {"Connecting.", "Connecting..", "Connecting..."};
int value = 0;
// ...
tx.setText(texts[value]);
value = (value+1)%3;
This way, you don't need your big messy if statement. You will need to find another way of notifying your thread when the job is done, rather than just having a fixed number of iterations.
Use TextSwitcher instead of TextView...It will work
I have a HashMap of Sound objects
private HashMap<Integer, Sound> sounds;
over which I'm trying to iterate to turn off all the sounds. I used
this answer to create an Iterator, but I'm still getting ConcurrentModificationException, though I'm sure there's no other code calling this at the same time.
public synchronized final void stopAll() {
Iterator<Entry<Integer, Sound>> soundEntries = sounds.entrySet().iterator();
while(soundEntries.hasNext())
{
Entry<Integer, Sound> s = soundEntries.next();
s.getValue().myOnCompletionListener = null;
s.getValue().fadeYourself();
}
sounds.clear();
}
In what way should I rewrite this to keep the ConcurrentModificationException from happening?
This is inside my Sound class:
private class soundFader extends AsyncTask<Sound, Void, Void>
{
#Override
protected Void doInBackground(Sound... arg0) {
arg0[0].fadeOut();
return null;
}
}
private void fadeOut()
{
float STEP_DOWN = (float) 0.10;
float currentVol = myVolume;
float targetVol = 0;
if(isSoundEnabled())
{
while(currentVol > targetVol)
{
currentVol -= STEP_DOWN;
mp.setVolume(currentVol, currentVol);
try {
Thread.sleep(70);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
mp.setVolume(0, 0);
onCompletion(mp);
sounds.remove(resource); // THIS LINE WAS MY ERROR
mp.seekTo(0);
nowPlaying = false;
}
public void fadeYourself()
{
soundFader fader = new soundFader();
fader.execute(this);
}
It is not permissible for one thread to modify a Collection while another thread is iterating over it.
If you want to modify only values (not keys) there is no need to use iterators here.
public synchronized final void stopAll() {
for(Sound s: sounds.values())
{
s.myOnCompletionListener = null;
s.fadeYourself();
}
sounds.clear();
}
Ninja edit:
You are removing items from the Collection while iterating. Hence the CoMo exception.
Since you are doing sounds.clear(); towards the end, you can remove the sounds.remove(resource); line.