SlideShare a Scribd company logo
Eden Bugdary Machluf
Advanced sessions
Threads
31/07/18
First,
> 3500 members
Largest Android Active
Community
Android Academy Staff
Yonatan Levin
Google Developer
Expert &
CTO @ KolGene
Yossi Segev
Mobile engineer
Colu
Refael Ozeri
Founder & CEO
Hero Apps
Eden Bugdary
Mobile developer @
AppNext
What Do We Do?
● Android Fundamentals
● Android UI / UX
● Community Hackathon
● Android Advanced
● Mentors Program
● Active community
Moscow
Mentors program
NOW!
https://bit.ly/2Nn9dAf
Logistics
facebook.com/groups/android.academy.ils/
https://bit.ly/2MWtigC
Android Advanced Course
22.8 - UI, GPU, Animations
16.9 - Clean Architecture
3.7 - CPU & Memory
31.7 - Threads & Network
Advanced #2   threading
Timor Surkis
Android Dev @ Gini Apps
Superhuman tech guy
Artyom Okun
Mobile Developer @ Colu
Awesome crunchy guy
Eden Bugdary Machluf
Advanced sessions
Threads
31/07/18
Eden Bugdary Machluf
Android Academy
Mobile developer @Appnext
What is a Thread?
CPU & processes
CPU Process
1 ...
Thread
1 ...
Thread
A thread of execution is the smallest sequence of
programmed instructions that can be managed
independently.
When launching an app...
Application
Process
Main
Thread
The main thread
UI rendering
Application
components
User interaction
Lifecycle callbacks
Main thread
Queue
The main thread is very busy
25
– When blocked - system shows ANR dialog
android.os.NetworkOnMainThreadException
– Exception on network operations
– Exclusive interaction with the UI
Leaving the Main thread
java.lang.Thread
public class MyThread extends Thread {
@Override
public void run() {
doStuff();
}
}
MyThread myThread = new MyThread();
myThread.start();
Getting back to the Main thread
Back to the main thread
We can:
– Activity.runOnUiThread(runnable)
– View.post(runnable)
Back to the Main Thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
Back to the Main Thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
Back to the Main Thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
From a View
mTextView.post(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
From a View
mTextView.post(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
From a View
mTextView.post(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
How does it work??
Threads in JAVA
new
MyThread()
start() run()
– One-time use only.
– Dies after executing it’s run() method.
– It’s not legal to start a thread more than once.
We have a problem
Create new thread consumes
system resources and memory.
How much memory?
Let’s make
threads
reusable
How it works?
We will need 3 players:
– Looper
– Message
– Handler
“
android.os.Looper
– Keeping its thread alive.
– Only one Looper per thread.
– Thread don’t get a Looper by default.*
– MessageQueue created when we create Looper.
android.os.Message
Two types of Messages:
– Data Message
– Task Message
android.os.Message
Message holding data.
Field Name Description
what int - Unique identifier
when long - timestamp
arg1, arg2 int - “Low cost” parameters
obj Object
data Bundle
android.os.Message
Message holding a task (Runnable).
Field Name Description
callback Runnable task
when long - timestamp
So it’s simple...
Task
Thread
Looper
MessageQueue
android.os.Handler
– Creating messages.
– Inserting messages to the queue.
– Removing messages in the queue.
– Consuming messages.
Thread
Looper
MessageQueue
Thread
Looper
MessageQueue
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Thread
Looper
MessageQueue
Handler
Handler
Questions?
60
Enough theory
Let’s see some code
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Road Map
Overview
1. A Looper is created and attached to a thread.
2. Handler is created.
3. The Handler create a Message.
4. The Handler insert the Message into the Looper queue.
5. The Handler is consuming/executing the message.
Overview
ꢈ A Looper is created and attached to a thread.
ꢈ Handler is created.
ꢈ The Handler create a Message.
ꢈ The Handler insert the Message into the Looper queue.
ꢈ The Handler is consuming/executing the message.
Fancy thread
public class FancyThread extends Thread {
@Override
public void run() {
Looper.prepare();
// Code is missing for simplicity
Looper.loop();
}
}
Overview
✓ A Looper is created and attached to a thread.
ꢈ Handler is created.
ꢈ The Handler create a Message.
ꢈ The Handler insert the Message into the Looper queue.
ꢈ The Handler is consuming/executing the message.
Handler creation
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do stuff
}
};
mHandler = new Handler(new Handler.Callback()) {
@Override
public boolean handleMessage(Message msg) {
return false; // return true if msg consumed
}
});
Handler creation
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do stuff
}
};
mHandler = new Handler(new Handler.Callback()) {
@Override
public boolean handleMessage(Message msg) {
return false; // return true if msg consumed
}
});
//Or...
Handler creation
mHandler = new Handler(Looper looper) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do stuff
}
};
mHandler = new Handler(Looper looper, new Handler.Callback()) {
@Override
public boolean handleMessage(Message msg) {
return false; // return true if msg consumed
}
});
Handler creation
mHandler = new Handler(Looper looper) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do stuff
}
};
mHandler = new Handler( Looper looper, new Handler.Callback()) {
@Override
public boolean handleMessage(Message msg) {
return false; // return true if msg consumed
}
});
//Or...
Fancy thread
public class FancyThread extends Thread {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler(Looper.myLooper(), callback);
Looper.loop();
}
}
Fancy thread
public class FancyThread extends Thread {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler(Looper.myLooper(), callback);
Looper.loop();
}
}
Fancy thread
public class FancyThread extends Thread {
//...
public Handler getHandler() {
return mHandler;
}
}
Overview
✓ A Looper is created and attached to a thread.
✓ Handler is created.
ꢈ The Handler create a Message.
ꢈ The Handler insert the Message into the Looper queue.
ꢈ The Handler is consuming/executing the message.
Creating a Message
Creating a Message
// Data messages
Message.obtain(Handler h);
Message.obtain(Handler h, int what);
Message.obtain(Handler h, int what, Object o);
Message.obtain(Handler h, int what, int arg1, int arg2);
Message.obtain(Handler h, int what, int arg1, int arg2, Object o);
// Task message
Message.obtain(Handler h, Runnable task);
Creating a Message
// Data messages
Message.obtain(Handler h);
Message.obtain(Handler h, int what);
Message.obtain(Handler h, int what, Object o);
Message.obtain(Handler h, int what, int arg1, int arg2);
Message.obtain(Handler h, int what, int arg1, int arg2, Object o);
// Task message
Message.obtain(Handler h, Runnable task);
Creating a Message with Handler
Message msg = handler.obtainMessage(/*...*/);
this.obtainMessage(/*...*/);
Creating a Message
Message message = Message.obtain(); // Return empty message from pool
message.what = 4;
message.arg1 = 100;
message.arg2 = 200;
message.obj = new Object();
message.setData(bundle);
Creating a Message
Message message = new Message(); !! Avoid !!
Overview
✓ A Looper is created and attached to a thread.
✓ Handler is created.
✓ The Handler create a Message.
ꢈ The Handler insert the Message into the Looper queue.
ꢈ The Handler is consuming/executing the message.
“
Insert a Message
to the queue
“
Inserting message to the queue
// Data messages
boolean handler.sendMessage(msg);
boolean handler.sendMessageAtFrontOfQueue(msg);
boolean handler.sendMessageDelayed(msg, 2000);
// and more...
“
Inserting message to the queue
// Task messages
boolean handler.post(Runnable r)
boolean handler.postAtFrontOfQueue(Runnable r)
boolean handler.postDelayed(Runnable r, long delayMillis)
// and more...
“
Creating and Inserting message to the queue
// Reference to our Handler
Handler fancyHandler = mFancyThread.getHandler();
// Create data message with what = 1
Message msg = fancyHandler.obtainMessage(1);
// Adding the message to the queue
fancyHandler.sendMessage(msg);
“
Creating and Inserting message to the queue
// Reference to our Handler
Handler fancyHandler = mFancyThread.getHandler();
// Create data message with what = 1
Message msg = fancyHandler.obtainMessage(1);
// Adding the message to the queue
fancyHandler.sendMessage(msg);
“
Creating and Inserting message to the queue
// Reference to our Handler
Handler fancyHandler = mFancyThread.getHandler();
// Create data message with what = 1
Message msg = fancyHandler.obtainMessage(1);
// Adding the message to the queue
fancyHandler.sendMessage(msg);
“
Creating and Inserting message to the queue
// Reference to our Handler
Handler fancyHandler = mFancyThread.getHandler();
// Create data message with what = 1
Message msg = fancyHandler.obtainMessage(1);
// Adding task message to the queue
fancyHandler.post(new MyRunnable());
Removing a Message
from the queue
Removing a Message from the queue
// Remove task message
Handler.removeCallbacks(Runnable r);
// Remove data messages
Handler.removeMessages(int what);
// Remove everything
Handler.removeCallbacksAndMessages(null);
// AND more...
Removing a Message from the queue
// Remove task message
Handler.removeCallbacks(Runnable r);
// Remove data messages
Handler.removeMessages(int what);
// Remove everything
Handler.removeCallbacksAndMessages(null);
// AND more...
Removing a Message from the queue
// Remove task message
Handler.removeCallbacks(Runnable r);
// Remove data messages
Handler.removeMessages(int what);
// Remove everything
Handler.removeCallbacksAndMessages(null);
// AND more...
Overview
✓ A Looper is created and attached to a thread.
✓ Handler is created.
✓ The Handler create a Message.
✓ The Handler insert the Message into the Looper queue.
ꢈ The Handler is consuming/executing the message.
Consuming Data Message
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Logger.d("Received message type - 1");
break;
case 2:
Logger.d("Received message type - 2");
break;
}
}};
Consuming Task Message
// No extra work is needed.
fancyHandler.post(new Runnable() {
@Override
public void run() {
// Will run on the Handler thread.
}
});
Keep it clean!
Don’t forget to call quit()
on your Looper when it is no
longer needed!
FancyActivity.java
@Override
protected void onStop() {
super.onStop();
mFancyThread.getHandler().post(new Runnable() {
@Override
public void run() {
Looper.myLooper().quit();
}
});
}
FancyActivity.java
@Override
protected void onStop() {
super.onStop();
mFancyThread.getHandler().sendEmptyMessage(-1);
}
FancyActivity.java
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case -1:
Looper.myLooper().quit();
return true;
}
}
Looper.quit() VS .quitSafely()
.quit() .quitSafely()
– All pending in the queue, Including
messages ready to be dispatched -
are discarded.
– Looper won’t process new
messages.
– Discards only messages that are not
ready to dispatch. Ready messages
will be dispatched.
– Looper won’t process new
messages.
– Only from API 18.
Overview
✓ A Looper is created and attached to a thread.
✓ Handler is created.
✓ The Handler create a Message.
✓ The Handler insert the Message into the Looper queue.
✓ The Handler is consuming/executing the message.
113
Phew… Questions?
114
P.S:
The Main thread is
just a “regular”
thread with a Looper.
The Main thread Looper
‒ The Main thread is the only thread with a Looper by default.
‒ The Looper cannot be stopped.
‒ You can access the Main thread Looper from anywhere
with: Looper.getMainLooper()
Main Thread Handler creation
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "I'm running on the Main thread.");
}
});
117
Messages passing is a powerful
async mechanism
but it can be hard to implement
from scratch.
Luckily, You don’t have
too...
HandlerThread
Flexible tasks chaining in a queue.
HandlerThread - Example use
case
“Our app onboarding flow has 6 different
network calls.”
HandlerThread
- A Thread with a “free” Looper implementation.
HandlerThread
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
//Make sure to call start() before creating the Handler!
handlerThread.start();
Handler handler = new Handler(mMyHandlerThread.getLooper());
Accessing the
thread looper
HandlerThread - Stopping
handlerThread.quit();
// or
handlerThread.quitSafely(); // API >= 18
HandlerThread- don’t forget
- Remember to quit().
- Call start() before calling getLooper().
HandlerThread
- Flexible, reusable tasks chaining.
- Guarantees thread safety.
- Implementation can take a while.
ThreadPoolExecutor
Easy work distribution between multiple threads.
ThreadPoolExecutor -
Example use case
“I need to allow my users to upload
multiple pictures from their gallery
simultaneously.”
ThreadPoolExecutor
– Managing a pool of thread.
– Creating/terminating threads as necessary.
– Utilize the Executor interface.
Executor.java
public interface Executor {
void execute(Runnable command);
}
Pre-defined Executors
// Single thread is executing the tasks in order.
Executors.newSingleThreadExecutor();
// Keeping the number of threads constant.
Executors.newFixedThreadPool(n);
// Dynamic size pool - grows/shrinks as needed.
// with 60 sec idle time per thread.
Executors.newCachedThreadPool();
Pre-defined Executors
// Single thread is executing the tasks in order.
Executors.newSingleThreadExecutor();
// Keeping the number of threads constant.
Executors.newFixedThreadPool(n);
// Dynamic size pool - grows/shrinks as needed.
// with 60 sec idle time per thread.
Executors.newCachedThreadPool();
Pre-defined Executors
// Single thread is executing the tasks in order.
Executors.newSingleThreadExecutor();
// Keeping the number of threads constant.
Executors.newFixedThreadPool(n);
// Dynamic size pool - grows/shrinks as needed.
// with 60 sec idle time per thread.
Executors.newCachedThreadPool();
How it works?
Task
ThreadPoolExecutor
Threads Pool
Queue
How it works?
Task
ThreadPoolExecutor
Threads Pool
Queue
How it works?
ThreadPoolExecutor
Threads Pool
Queue
How it works?
Task
ThreadPoolExecutor
Threads Pool
Queue
How it works?
Task
ThreadPoolExecutor
Threads Pool
Queue
How it works?
ThreadPoolExecutor
Threads Pool
Queue
Stopping ThreadPoolExecutor
mExecutor.shutdown();
mExecutor.shutdownNow();
ThreadPoolExecutor
– Easy to deal with threads work distribution.
– Useful out-of-the-box implementations available.
– Implementing efficiently requires time.
Summary
– All the threads are made from 3 main components:
Looper, Handler and Messages.
– We can create our own thread just like android system
does.
– Android can make our lives easier if we choose to use
the (kind of) out of box ready components.
Eden Bugdary Machluf
Thank you!

More Related Content

PPTX
Advanced #3 threading
PDF
The Ring programming language version 1.10 book - Part 59 of 212
PDF
Android Architecture Component in Real Life
PDF
Architecture Components In Real Life Season 2
PDF
Android Performance #4: Network
PDF
Kotlin coroutine - the next step for RxJava developer?
PDF
droidcon Transylvania - Kotlin Coroutines
ODP
Android App Development - 07 Threading
Advanced #3 threading
The Ring programming language version 1.10 book - Part 59 of 212
Android Architecture Component in Real Life
Architecture Components In Real Life Season 2
Android Performance #4: Network
Kotlin coroutine - the next step for RxJava developer?
droidcon Transylvania - Kotlin Coroutines
Android App Development - 07 Threading

What's hot (12)

PPTX
Scaling django
PDF
Performance #1: Memory
PPTX
WaveEngine 2D components
PPTX
WaveEngine 3D components
PDF
The Ring programming language version 1.7 book - Part 52 of 196
PDF
Android Threading
PDF
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
PPTX
Java concurrency - Thread pools
ODP
Concurrent Programming in Java
PDF
Brubeck
PDF
Understanding greenlet
PPTX
9 services
Scaling django
Performance #1: Memory
WaveEngine 2D components
WaveEngine 3D components
The Ring programming language version 1.7 book - Part 52 of 196
Android Threading
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
Java concurrency - Thread pools
Concurrent Programming in Java
Brubeck
Understanding greenlet
9 services
Ad

Similar to Advanced #2 threading (20)

PPTX
Lecture #2 threading, networking & permissions final version #2
PPT
Tech talk
PPTX
Async task, threads, pools, and executors oh my!
PDF
Android Concurrency Presentation
PPT
Android - Thread, Handler and AsyncTask
PDF
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
PPTX
Thread_Handlers_and_Executors_Presentation.pptx
PDF
Tools and Techniques for Understanding Threading Behavior in Android
ODP
Architecture your android_application
PDF
Android concurrency
PDF
Programming Sideways: Asynchronous Techniques for Android
PPTX
Threads in Mobile Application Development.pptx
PDF
Multithreading Introduction and Lifecyle of thread
PPTX
Android Thread
PDF
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
PPTX
Efficient Android Threading
PPT
Inside the Android application framework - Google I/O 2009
PPTX
Performance #6 threading
PPTX
Tools and Techniques for Understanding Threading Behavior in Android*
PPTX
Java Multithreading - how to create threads
Lecture #2 threading, networking & permissions final version #2
Tech talk
Async task, threads, pools, and executors oh my!
Android Concurrency Presentation
Android - Thread, Handler and AsyncTask
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Thread_Handlers_and_Executors_Presentation.pptx
Tools and Techniques for Understanding Threading Behavior in Android
Architecture your android_application
Android concurrency
Programming Sideways: Asynchronous Techniques for Android
Threads in Mobile Application Development.pptx
Multithreading Introduction and Lifecyle of thread
Android Thread
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
Efficient Android Threading
Inside the Android application framework - Google I/O 2009
Performance #6 threading
Tools and Techniques for Understanding Threading Behavior in Android*
Java Multithreading - how to create threads
Ad

More from Vitali Pekelis (20)

PDF
Droidkaigi2019thagikura 190208135940
PDF
Droidkaigi 2019
PPTX
Google i o & android q changes 2019
PPTX
Android Q 2019
PPTX
Advanced #6 clean architecture
PPTX
Advanced #4 GPU & Animations
PDF
Advanced #2 networking
PPTX
Advanced #1 cpu, memory
PPTX
All the support you need. Support libs in Android
PPTX
How to build Sdk? Best practices
PPTX
Di & dagger
PPTX
Android design patterns
PPTX
Mobile ui fruit or delicious sweets
PPTX
Lecture #4 c loaders and co.
PPTX
Session #4 b content providers
PPTX
Advanced #2 - ui perf
PDF
Android meetup
PPTX
Android design lecture #3
PPTX
From newbie to ...
PDF
Working better together designers & developers
Droidkaigi2019thagikura 190208135940
Droidkaigi 2019
Google i o & android q changes 2019
Android Q 2019
Advanced #6 clean architecture
Advanced #4 GPU & Animations
Advanced #2 networking
Advanced #1 cpu, memory
All the support you need. Support libs in Android
How to build Sdk? Best practices
Di & dagger
Android design patterns
Mobile ui fruit or delicious sweets
Lecture #4 c loaders and co.
Session #4 b content providers
Advanced #2 - ui perf
Android meetup
Android design lecture #3
From newbie to ...
Working better together designers & developers

Recently uploaded (20)

PPTX
Introduction to Artificial Intelligence
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
history of c programming in notes for students .pptx
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
AI in Product Development-omnex systems
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
System and Network Administraation Chapter 3
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Digital Strategies for Manufacturing Companies
PDF
System and Network Administration Chapter 2
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Introduction to Artificial Intelligence
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Upgrade and Innovation Strategies for SAP ERP Customers
history of c programming in notes for students .pptx
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Odoo Companies in India – Driving Business Transformation.pdf
Operating system designcfffgfgggggggvggggggggg
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
AI in Product Development-omnex systems
Design an Analysis of Algorithms I-SECS-1021-03
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
System and Network Administraation Chapter 3
Softaken Excel to vCard Converter Software.pdf
Odoo POS Development Services by CandidRoot Solutions
Digital Strategies for Manufacturing Companies
System and Network Administration Chapter 2
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus

Advanced #2 threading