Processes and threads
- process
- An instance of a program (usually only one instance of a program)
- thread
- The smallest executable unit
- A process can have multiple threads (a process must have one thread)
A simple explanation of processes and threads
How threads are created
- Thread class inheritance
- If run() is called directly, it suspends the current method and waits for run() to complete, just like normal method calls
class ThreadDemo extends Thread { // No parameter constructor ThreadDemo(){ } public void run(a){ // Custom code}}public statin void main(String[] args){ // Call the no-argument constructor to create the thread object ThreadDemo td = new ThreadDemo(); /* There is a difference between starting a new thread and calling the run() method. The run() method pushes the current thread, waits for the run() method to complete, and then returns to the current method */ td.start(); } Copy the code
- Implement the Runnable interface
- All three are essentially implementations of Runnable
class RunDemo implements Runnable {
RunDemo(){}
// Implement the run() method of the interface
public void run(a){
// Custom code}}public static void main(String[] args){
Runnable runDemo = new RunDemo();
// Call the parameter constructor of Thread and pass in an implementation of the Thread interface to create and start the Thread
new Thread(runDemo).start();
}
Copy the code
- Implement Callable interface
-
Callable needs to be wrapped as a Future
-
The Future needs to be wrapped as FutureTask
-
FutureTask actually implements the RunnableFuture interface
-
The RunnableFuture interface is a combination of Runnable and Future
-
So, a Callable is essentially a Runnable
-
How a thread is created that can return values
3.1 Callable + Future
public class CallAndFuture implements Callable{ private String name; public CallAndFuture(String name ){ this.name = name; } public String call(a){ return "11111133333" + this.name; } public static void main (String[] args) throws ExecutionException, InterruptedException { /* code */ CallAndFuture callOne = new CallAndFuture("The one"); CallAndFuture callTwo = new CallAndFuture("The results of two"); CallAndFuture callThree = new CallAndFuture("The three"); ExecutorService es = Executors.newFixedThreadPool(3); Future futureOne = es.submit(callOne); System.out.println(futureOne.get()); Future futureTwo = es.submit(callTwo); System.out.println(futureTwo.get()); Future futureThree = es.submit(callThree); System.out.println(futureThree.get()); es.shutdown(); } Copy the code
3.2 + FutureTask Callable
-
-
The get() method blocks the main thread, usually using get(long timeout, TimeUnit unit) with a timeout.
-
Generally, the thread execution results are obtained after other tasks are completed. If subsequent results depend on the results of thread execution, you can block the wait (but why?).
Thread state
- NEW
- Run (RUNNABLE)
- ready
- In the operation of the
- WAITING.
- Waiting for action (notification or interrupt) from another thread
- They are BLOCKED.
- Due to the lock block
- Timeout waiting (TIMED_WAITING)
- Wait with an end time
- After the specified time, the queue automatically returns to the ready state
- The sleep() method raises this state
- Death (TERMINATED)
- completed
The final execution method of a thread
native void start0()
start0()
Methods are composed of static methodsstatic native void registerNatives()
Prepare for initialization- So, in essence, Java does not start threads. Instead, the underlying C++ implementation method start0 does
Common methods of threading
- wait
- Calling this method to put the thread into the wait state releases the lock
- join
- Thread enforcement, commonly known as queue jumping. Whoever called will be blocked.
- notify
- Wakes up a thread in the wait queue to compete for CPU
- notifyAll
- Wake up all threads in the wait queue to compete for CPU
- Stop (not recommended)
- Destroy (not recommended)
- yield
- Thread comity. Exit the CPU and recompete with other threads.
- May again compete to CPU, completely depends on CPU mood.
- sleep
- Calling this method blocks the thread and does not release the lock
Synchronization mechanism for threads
synchronized
- Methods can be locked
public synchronized void test(){}
- Blocks of code can be locked
synchronized(obj){}
- Methods can be locked
Lock
interface- Blocks of code can be locked
- Already locked
ReentrantLock lock = new ReentrantLock(); try{ / / lock lock.lock(); }finally{ / / unlock lock.unlock(); } Copy the code
- LockSupport
class FIFOMutex { private final AtomicBoolean locked = new AtomicBoolean(false); private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>(); public void lock(a) { boolean wasInterrupted = false; Thread current = Thread.currentThread(); waiters.add(current); // Block while not first in queue or cannot acquire lock while(waiters.peek() ! = current || ! locked.compareAndSet(false.true)) { LockSupport.park(this); if (Thread.interrupted()) // ignore interrupts while waiting wasInterrupted = true; } waiters.remove(); if (wasInterrupted) // reassert interrupt status on exit current.interrupt(); } public void unlock(a) { locked.set(false); LockSupport.unpark(waiters.peek()); }}}Copy the code
- ReentrantReadWriteLock Reentrant read/write lock
public class ReadWriteLockDemo { public static void main(String[] args) { Note note = new Note(); for (int i = 0; i < 100; i++) { if( i%10= =0) {new Thread(new TakeNote(note)).start(); } else { new Thread(newViewNote(note)).start(); }}}}class TakeNote implements Runnable{ private Note note = null; public TakeNote(Note n){ this.note = n; } @Override public void run(a) { try { this.note.add("= = = =" + Thread.currentThread().getName()); } catch(InterruptedException e) { e.printStackTrace(); }}}class ViewNote implements Runnable { private Note note = null; public ViewNote(Note note){ this.note = note; } @Override public void run(a) { try { this.note.get(); } catch(InterruptedException e) { e.printStackTrace(); }}}class Note{ private ArrayList<String> al = new ArrayList<String>(); private ReentrantReadWriteLock rtRw = new ReentrantReadWriteLock(); private Lock readLock = rtRw.readLock(); private Lock writeLock = rtRw.writeLock(); public void add(String note) throws InterruptedException { writeLock.lock(); System.out.println("===**** taking notes taking notes ===" + Thread.currentThread().getName()); al.add(note); Thread.sleep(5000); System.out.println("===**** finish notes ===" + Thread.currentThread().getName()); writeLock.unlock(); } public String get(a) throws InterruptedException { // Read lock can be entered multiple times readLock.lock(); System.out.println("=== viewing notes ===" + Thread.currentThread().getName()); if(al.size() == 0) {readLock.unlock(); return ""; } String re = al.get(al.size()-1); Thread.sleep(2000); System.out.println("=== Look up your notes ===" + Thread.currentThread().getName()); readLock.unlock(); returnre; }}Copy the code
StampedLock
The seal lock
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally{ sl.unlockWrite(stamp); }}double distanceFromOrigin(a) { // A read-only method
// Get optimistic read locks
long stamp = sl.tryOptimisticRead();
double currentX = x, currentY = y;
if(! sl.validate(stamp)) { stamp = sl.readLock();try {
currentX = x;
currentY = y;
} finally{ sl.unlockRead(stamp); }}return Math.sqrt(currentX * currentX + currentY * currentY);
}
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
// Try converting to write lock
long ws = sl.tryConvertToWriteLock(stamp);
if(ws ! =0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else{ sl.unlockRead(stamp); stamp = sl.writeLock(); }}}finally{ sl.unlock(stamp); }}}}Copy the code
Priority of the thread
- A higher priority is more likely to be executed by the CPU than a lower priority
- The value range of the priority is a positive integer
[1-10]
- SetPriority () sets the priority
- Some constants of the priority
Thread.MIN_PRIORITY
(1)Thread.NORM_PRIORITY
(5)Thread.MAX_PRIORITY
(10)
Daemon threads
- Normal threads are user threads
setDaemon(true)
Start daemon thread- The virtual machine must wait for all user threads to complete, but not for the daemon thread to complete
- Common daemon threads
- GC garbage collection thread
Thread communication
Producer-consumer model
Lock the nature
- What exactly does a lock lock? (Only two)
- Instance object (there can be more than one)
- Class object (there is only one Class object for a Class)
Some problems with thread concurrency
False awaken
- Wakes up multiple related threads, but does not actually meet the execution condition
- Use of wait and notifyAll
- Wait is placed in a while loop to avoid the problem of false awakenings
A deadlock
- Four necessary conditions for deadlocks
- The mutex
- Hold and wait
- Resources must not be forcibly taken away
- Circular waiting (the required resource is in someone else’s hands)