Running methods on different threads - multithreading

simply put for a hw problem I need to run a bubble sort with 3 million elements. Do this normally. and then sort 4 individual lists (not nearly accurate but is all thats required) of 750000 elements each on a different thread.
I have a class that extends thread that simply prints a line if im running the thread. But I'm not sure how to get it to run a method
class thread extends Thread{
override def run()
{
// Displaying the thread that is running
println("Thread " + Thread.currentThread().getName() +" is running.")
}
}
//this for loop is in an object
for (c <- 1 to 5)
{
var th = new thread()
th.setName(c.toString())
th.start()
}

I am going to stick to answering the question you asked instead of trying to do your homework for you. I hope that is enough to get your started trying things out for yourself.
Recall that class names should be capitalized. That is probably a good thing to remember as your instructor will probably mark you down if you forget that during an exam.
class MyThread extends Thread{
override def run() = {
// Displaying the thread that is running
println("Thread " + Thread.currentThread().getName() +" is running.")
sort()
}
def sort() = {
// my sorting code here
}
}
If your instructor has not restricted you to using Thread only, I would also, similar to Luis Miguel Mejía Suárez, recommend Future instead of Thread. The syntax it uses is cleaner and preferable for how I would do multithreading in a professional setting. However, the choice may not be yours, so if your teacher says use Thread, use Thread.
For a primer on using Futures, see here.
Good luck!

Related

Dice roller app, formatting attribute id calls using Kotlin

I'm taking a kotlin basics course from the android devs website and we have to create an app that allows you to roll a dice and display an image with the number that rolled.
I can make a condition for each possible roll number, but i feel like that's dumb and with formatted reference id calls it should be done way better but I don't know how to accomplish that in kotlin using Android Studio. Any helpers?
package com.example.diceroller
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
/**
* Calls the onCreate() method to initiate the app in its MainActivity.
* setOnClickListener to look for activity in the window (button presses/taps).
*/
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.button)
rollButton.setOnClickListener { rollDice() }
/* Toast.makeText(this,"Dice Rolled!", Toast.LENGTH_SHORT).show() | Shows alert (toast) at bottom of the screen. */
}
/*
* Initiates a 'Dice' instance with 6 sides.
* calls the roll() method to call rng between 1 and numSides.
*
*/
private fun rollDice() {
val dice = Dice(6)
val diceRoll = dice.roll()
val diceImage: ImageView = findViewById(R.id.imageView)
if (diceRoll == 1){ diceImage.setImageResource(R.drawable.dice_1) }
else if (diceRoll == 2){ diceImage.setImageResource(R.drawable.dice_2) }
//Instead of doing it the "dumb way" I want to call the id depending on diceRoll value.
}
}
class Dice(private val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
If you're asking how to add 1 or whatever to "R.drawable.dice_" and then turn that string into a resource ID, then you can follow the accepted answer here: https://stackoverflow.com/a/2414165/13598222
Personally I wouldn't recommend that - it's brittle since the compiler can't connect what you're doing to a specific resource. So it can't warn you if you change the resource name (so your code doesn't match anymore), and things like Proguard can end up stripping out "unused" resources (because it can't tell you're using them) and you have to manually fix that.
Probably the most standard way to do what you're doing is to use a when clause, and just return the drawable ID from that:
val drawableId = when(diceRoll) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
diceImage.setImageResource(drawableId)
Sure it's a little repetitive, but it's a standard pattern, it's very easy to understand and work with, and you're explicitly handling all the cases by adding the (required) else clause - you could also handle 6 explicitly and make the else throw an out-of-range message, in case your roll function somehow sends an invalid value (which it could, since you're hardcoding six values here, but your Dice class can have an arbitrary number!)
Another way you could do it is to have a lookup, like a Map:
private val diceDrawables = mapOf {
1 to R.drawable.dice_1,
2 to R.drawable.dice_2,
3 to R.drawable.dice_3,
4 to R.drawable.dice_4,
5 to R.drawable.dice_5,
6 to R.drawable.dice_6
}
and then your image setting code can be nice and short:
diceImage.setImageResource(diceDrawables[diceRoll] ?: throw Exception("No image for roll: $diceRoll))
This isn't the "dumb" way to do things, it's neat and tidy and avoids repetition (e.g. repeating the setImageResource call). Getting clever with your code logic can cut down a few lines, but it can also make things much more complex and fragile, and just harder to work with. Sometimes that kind of thing is the right call, but in this situation I think this is probably the best compromise. Your call though!
Create a list using those resource ids.
private fun rollDice() {
val diceImages = listOf(R.drawable.dice_1, R.drawable.dice_2, ...)
val diceImage: ImageView = findViewById(R.id.imageView)
discImage.setImageResource(discImages.random())
}

QT slot ignores while loop

Hello i'm try to create an application in QT with two thread but i have an issue :
I have a slot which run when i click on a pushbutton, and on the click it is supposed to change the name of a label called lValeur. But it change the text only once . Play help me i want to die ...
Here is the interesting part of my code :
void IHM::ClicButtonPer()
{
ButtonDem->setEnabled(true) ;
ButtonPer->setEnabled(false) ;
QString val ;
QTimer attendre ;
do
{
val = "Valeur : " ;
val += valeur ;
lValeur->setText(val) ;
attendre.start(1000) ;
while(attendre.isActive())
QApplication::processEvents() ;
if(ButtonPer->isEnabled())
break ;
}while(1) ;
}
and the connect function which execute the slot :
connect(ButtonPer, SIGNAL(clicked()), this, SLOT(ClicButtonPer())) ;
EDIT : that's multithreading because i have another thread which communicate with a TCP server
EDIT 2 :
connect(&m_timer, &QTimer::timeout, this, &IHM::on_timer);
this code just return me an error on &IHM::on_timer: cannot take the address of an rvalue of type 'void'
EDIT 3 (and the last one) :
I change connect(&m_timer, &QTimer::timeout, this, &IHM::on_timer);
with connect(&m_timer, SIGNAL(timeout()), this, SLOT(on_timer)) ;
Hope it will help someone
Very strange code. You need to learn the basics of programming. A timer is an entity that is not used in loops. Timers are usually used to repeatedly perform any action at predetermined equal intervals of time, but avoiding loops.
As for Qt and the QTimer class,
you need to create a QTimer object in a nonlocal scope. You can add the variable declaration to the IHM class header. In the simplest case, you also need to create a slot method.
class IHM : public...
{
...
private:
QTimer m_timer;
private slots:
void on_timer();
}
Then in the IHM cpp file you need to connect the timeout signal of the timer the slot. It can be done in the IHM constructor.
connect(&m_timer, &QTimer::timeout, this, &IHM::on_timer);
Put the code you need to be called repeatedly, to the slot body. Start and stop the timer wherever you need. For example:
void IHM::ClicButtonPer()
{
...
m_timer.start(1000);
}
void IHM::on_timer()
{
...
val += valeur;
lValeur->setText(val);
if(ButtonPer->isEnabled())
{
m_timer.stop();
}
}
As for the issue "it change the text only once" you need to read about Qt event loop. I can suggest
Signals & Slots
Threads_Events_QObjects.
You can also set a breakpoint to the line attendre.start(1000); then go down the steps and see what conditions are actually met.
Read also:
Threading Basics
Multithreading Technologies in Qt
Threads and QObjects

multi threading in java with for loop

there is an list of student entity.
List<Student> student = new Arraylist<Student>();
where
public student{
private id;
private name;
private class;
//setter and getter
}
By the foreach loop:
for(Student std : student){
System.out.println(std.getName());
}
above is the normal way. But how to print them with multithreading?
three student details together print. means taking three threads toghter
This doesn't serve any practical purpose.
for(Student std:student){
new Thread(()->{
System.out.println(std.getName);
System.out.println(std.getName);
}).start();
}
This is also worse than the answer above.
A simple solution:
studentList.parallelStream().forEach(System.out::println);
This turns your list into a stream, and for each element in that stream, System.out.println() is invoked.
The non-stream solution is of course much more complicated. It would required you to define multiple threads, including a "pattern" how these threads work on that shared list.
For doing it with "raw threads": that is simply, straight forward stuff: you have to "slice" your data into buckets, and then define threads that work different buckets. See here as starting point.

Greenfoot Actor not in World error

When my enemy gets to the bottom of the screen I want to remove and if the enemy gets hit by bullets i want to remove it. The error is : java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed.
I think the problem is because there is two calls to removeObject or the getOneIntersectingObject method is causing an error. How do I fix this?
This is the code causing the error
public class Enemy extends Actor
{
public void act()
{
setLocation(getX(), getY() + 3);
if (getY() > getWorld().getHeight() + 30 )
getWorld().removeObject(this);
Actor fire = getOneIntersectingObject(Fire.class);
if(fire != null)
getWorld().removeObject(this);
}
}
Greenfoot doesn't allow any interactions with the world after an actor has been removed from it. If your Y coordinate causes this actor to be removed from the world in the first if statement, it is an error to call getOneIntersectingObject afterwards.
There's several ways to solve this: you could wrap the ensuing lines in an else clause, you could make an early return if you remove yourself in the first if, or you could use a boolean flag to keep track of whether you want to remove yourself, but only do the removal as the very last item in the act() method.

Multi-threading on a foreach loop?

I want to process some data. I have about 25k items in a Dictionary. IN a foreach loop, I query a database to get results on that item. They're added as value to the Dictionary.
foreach (KeyValuePair<string, Type> pair in allPeople)
{
MySqlCommand comd = new MySqlCommand("SELECT * FROM `logs` WHERE IP = '" + pair.Key + "' GROUP BY src", con);
MySqlDataReader reader2 = comd.ExecuteReader();
Dictionary<string, Dictionary<int, Log>> allViews = new Dictionary<string, Dictionary<int, Log>>();
while (reader2.Read())
{
if (!allViews.ContainsKey(reader2.GetString("src")))
{
allViews.Add(reader2.GetString("src"), reader2.GetInt32("time"));
}
}
reader2.Close();
reader2.Dispose();
allPeople[pair.Key].View = allViews;
}
I was hoping to be able to do this faster by multi-threading. I have 8 threads available, and CPU usage is about 13%. I just don't know if it will work because it's relying on the MySQL server. On the other hand, maybe 8 threads would open 8 DB connections, and so be faster.
Anyway, if multi-threading would help in my case, how? o.O I've never worked with (multiple) threads, so any help would be great :D
MySqlDataReader is stateful - you call Read() on it and it moves to the next row, so each thread needs their own reader, and you need to concoct a query so they get different values. That might not be too hard, as you naturally have many queries with different values of pair.Key.
You also need to either have a temp dictionary per thread, and then merge them, or use a lock to prevent concurrent modification of the dictionary.
The above assumes that MySQL will allow a single connection to perform concurrent queries; otherwise you may need multiple connections too.
First though, I'd see what happens if you only ask the database for the data you need ("SELECT src,time FROMlogsWHERE IP = '" + pair.Key + "' GROUP BY src") and use GetString(0) and GetInt32(1) instead of using the names to look up the src and time; also only get the values once from the result.
I'm also not sure on the logic - you are not ordering the log events by time, so which one is the first returned (and so is stored in the dictionary) could be any of them.
Something like this logic - where each of N threads only operates on the Nth pair, each thread has its own reader, and nothing actually changes allPeople, only the properties of the values in allPeople:
private void RunSubQuery(Dictionary<string, Type> allPeople, MySqlConnection con, int threadNumber, int threadCount)
{
int hoppity = 0; // used to hop over the keys not processed by this thread
foreach (var pair in allPeople)
{
// each of the (threadCount) threads only processes the (threadCount)th key
if ((hoppity % threadCount) == threadNumber)
{
// you may need con per thread, or it might be that you can share con; I don't know
MySqlCommand comd = new MySqlCommand("SELECT src,time FROM `logs` WHERE IP = '" + pair.Key + "' GROUP BY src", con);
using (MySqlDataReader reader = comd.ExecuteReader())
{
var allViews = new Dictionary<string, Dictionary<int, Log>>();
while (reader.Read())
{
string src = reader.GetString(0);
int time = reader.GetInt32(1);
// do whatever to allViews with src and time
}
// no thread will be modifying the same pair.Value, so this is safe
pair.Value.View = allViews;
}
}
++hoppity;
}
}
This isn't tested - I don't have MySQL on this machine, nor do I have your database and the other types you're using. It's also rather procedural (kind of how you would do it in Fortran with OpenMPI) rather than wrapping everything up in task objects.
You could launch threads for this like so:
void RunQuery(Dictionary<string, Type> allPeople, MySqlConnection connection)
{
lock (allPeople)
{
const int threadCount = 8; // the number of threads
// if it takes 18 seconds currently and you're not at .net 4 yet, then you may as well create
// the threads here as any saving of using a pool will not matter against 18 seconds
//
// it could be more efficient to use a pool so that each thread takes a pair off of
// a queue, as doing it this way means that each thread has the same number of pairs to process,
// and some pairs might take longer than others
Thread[] threads = new Thread[threadCount];
for (int threadNumber = 0; threadNumber < threadCount; ++threadNumber)
{
threads[threadNumber] = new Thread(new ThreadStart(() => RunSubQuery(allPeople, connection, threadNumber, threadCount)));
threads[threadNumber].Start();
}
// wait for all threads to finish
for (int threadNumber = 0; threadNumber < threadCount; ++threadNumber)
{
threads[threadNumber].Join();
}
}
}
The extra lock held on allPeople is done so that there is a write barrier after all the threads return; I'm not quite sure if it's needed. Any object would do.
Nothing in this guarantees any performance gain - it might be that the MySQL libraries are single threaded, but the server certainly can handle multiple connections. Measure with various numbers of threads.
If you're using .net 4, then you don't have to mess around creating the threads or skipping the items you aren't working on:
// this time using .net 4 parallel; assumes that connection is thread safe
static void RunQuery(Dictionary<string, Type> allPeople, MySqlConnection connection)
{
Parallel.ForEach(allPeople, pair => RunPairQuery(pair, connection));
}
private static void RunPairQuery(KeyValuePair<string, Type> pair, MySqlConnection connection)
{
MySqlCommand comd = new MySqlCommand("SELECT src,time FROM `logs` WHERE IP = '" + pair.Key + "' GROUP BY src", connection);
using (MySqlDataReader reader = comd.ExecuteReader())
{
var allViews = new Dictionary<string, Dictionary<int, Log>>();
while (reader.Read())
{
string src = reader.GetString(0);
int time = reader.GetInt32(1);
// do whatever to allViews with src and time
}
// no iteration will be modifying the same pair.Value, so this is safe
pair.Value.View = allViews;
}
}
The biggest problem that comes to mind is that you are going to use multithreading to add values to a dictionary, which isn't thread safe.
You'll have to do something like this to make it work, and you might not get that much of a benefit from implementing it this was as it still has to lock the dictionary object to add a value.
Assumptions:
There is a table People in your
database
There are alot of people in
your database
Each database query adds overhead you are doing one db query for each of the people in your database I would suggest it was faster to get all the data back in one query then to make repeated calles
select l.ip,l.time,l.src
from logs l, people p
where l.ip = p.ip
group by l.ip, l.src
Try this with a loop in a single thread, I belive this will be much faster then your existing code.
With in your existing code another thing you can do is to take the creation of the MySqlCommand out of the loop, prepare it in advance and just change the parameter. This should speed up execution of the SQL. see http://dev.mysql.com/doc/refman/5.0/es/connector-net-examples-mysqlcommand.html#connector-net-examples-mysqlcommand-prepare
MySqlCommand comd = new MySqlCommand("SELECT * FROM `logs` WHERE IP = ?key GROUP BY src", con);
comd.prepare();
comd.Parameters.Add("?key","example");
foreach (KeyValuePair<string, Type> pair in allPeople)
{
comd.Parameters[0].Value = pair.Key;
If you are using mutiple threads, each thread will still need there own Command, at lest in MS-SQL this would still be faster even if you recreated and prepared the statment every time, due to the ability for the SQL server to be able to cache the execution plan of a paramertirised statment.
Before you do anything else, find out exactly where the time is being spent. Check the execution plan of the query. The first thing I'd suspect is a missing index on logs.IP.
18 minutes for something like this seems much too long to me. Even if you can cut the execution time in eight by adding more threads (which is unlikely!) you still end up using more than 2 minutes. You could probably read the whole 25k rows into memory in less than five seconds and do the necessary processing in memory...
EDIT: Just to clarify, I'm not advocating actually doing this in memory, just saying that it looks like there's a bigger bottleneck here that can be removed.
I think if you are running this on a multi core machine you could gain benefits from multi threading.
However the way I would approach it is to first look at unblocking the thread you are currently using by making asynchronous database calls. The call backs will execute on background threads, so you will get some multi core benefit there and you won't be blocking threads waiting for the db to come back.
For IO intensive apps like this example sounds like you are likely to see improved throughput depending on what load the db can handle. Assuming the db scales to handle more than one concurrent request you should be good.
Thanks everyone for your help. Currently I am using this
for (int i = 0; i < 8; i++)
{
ThreadPool.QueueUserWorkItem(addDistinctScres, i);
}
ThreadPool to run all the threads. I use the method provided by Pete Kirkham, and I'm creating a new connection per thread.
Times went down to 4 minutes.
Next I'll make something wait for the callback of the threadpool? before performing other functions.
I think the bottleneck now is the MySQL server, because the CPU usage has drops.
#odd parity I thought about that, but the real thing is waaay more than 25k rows. Idk if that'd work.
This sound like the perfect job for map/reduce, i am not a .Net-programmer, but this seems like a reasonable guide:
http://ox.no/posts/minimalistic-mapreduce-in-net-4-0-with-the-new-task-parallel-library-tpl

Resources