Concurrent programming
1. Three Elements of Concurrent Programming
- Atomicity: Either all done or all failed
- Orderability: The ordered progress of program threads (through locks)
- Visibility: The process of modifying is visible
The nature of concurrent programming: making full use of CPU resources
The difference between a process and a thread
Processes are the basic units of resource allocation, such as qq. These are processes
Threads are the basic unit of task scheduling, and processes contain multiple threads
There are two threads main gc by default in java
1.1 Multithreaded Review
-
Thread and Runnable (common)
//MyTread package com.thread; public class MyThread01 extends Thread{ @Override public void run() { System.out.println("i start"); } } ///test public class ThreadDemo01 { public static void main(String[] args) { Thread t1 = new MyThread01(); t1.start(); } } //runnable public class Runable1 implements Runnable{ @Override public void run() { System.out.println("I started"); } } //test public class RunTest { public static void main(String[] args) { new Thread(new Runable1()).start(); } }
1.2 Daemon and non-daemon threads
- Daemon thread: Use the setDaemon method to set the thread as a daemon thread before start, and the daemon thread cannot execute until other non-daemon threads have finished executing
- Non-daemon threads: Threads we normally use default to non-daemon threads
1.3 Why start a thread when we start it instead of calling the run method directly
Reason: To call the run method directly is to call the run as a normal method. The run method is a normal method. There is no real thread to start, so starting a thread requires that the start method be removed.
1.4 join method
This thread will execute first after a practical join
Status of 1.5 Threads
- new students
- Run runnable
- Blocked bloked
- Timeout Wait
- termination
1.6 wait/sleep differences
-
wait is object --> must be in synchronous code block, no exceptions need to be caught, locks will be released
-
sleep is Thread----> locks will not be released and exceptions need to be caught
2. synchronized keywords
2.1 Locked Objects
Loading instance methods are added to objects, and static methods are added to.class files
2.2 The nature of locks
Multiple threads can cause problems when sharing resources. By locking, we can ensure that only one thread can access resources at a time
2.3 lock (**)
The essence of traditional Synchronized: Queuing, releasing locks when the object runs out of locks
lock interface common implementation class ReentranLock
Fair Lock: First come, first come
Unfair Lock: Can queue (default)
lock.lock();//Locking try{ Business code; }catch{ } finally{ lock.unlock();//Unlock }
Differences between Synchronized and lock
- Synchronized is a java keyword and lock is a java class
- Synchronized could not determine the state of the lock, lock could determine the state of the lock
- Synchronized automatically releases locks. Locks must be released manually. Not releasing locks causes deadlocks
- Syn thread 1 blocked thread 2 waiting, lock lock lock not waiting
- syn can be re-locked without interrupting unfair, lock, re-lock
- syn works with a small amount of code, lock works with a large amount of code
3 wait and notify
3.1 Producer and Consumer
Notify the producer if there is no product
Tips: judge waiting, business, notification
public class Customer implements Runnable{ private Box b; public Customer(Box b) { this.b = b; } @Override public void run() { while (true) { b.get(); } } } public class producer implements Runnable { private Box b; public producer(Box b) { this.b = b; } @Override public void run() { for (int i = 5; i > 0; i--) { b.put(i); } } } //box public class Box { private int milk; private boolean state = false; public synchronized void put(int milk){ if (state){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.milk=milk; System.out.println("Sent"+milk+"milk"); state = true; notifyAll(); } public synchronized void get(){ if (!state){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("User got it"+this.milk+"milk"); state=false; notifyAll(); } } //test public class ThreadDemo { public static void main(String[] args) { Box b = new Box(); producer p =new producer(b); Customer c = new Customer(b); Thread t1 = new Thread(p); Thread t2 = new Thread(c); t1.start(); t2.start(); } }
public class PcTestDemo { public static void main(String[] args) { Pcdemo pc = new Pcdemo(); new Thread(()->{ try { for (int i = 0; i < 10; i++) { pc.add(); } } catch (InterruptedException e) { e.printStackTrace(); } },"A").start(); new Thread(()->{ try { for (int i = 0; i < 10; i++) { pc.denumber(); } } catch (InterruptedException e) { e.printStackTrace(); } },"B").start(); } } class Pcdemo{ private int number=0; public synchronized void add() throws InterruptedException { //Determine if you need to wait while (number!=0){ this.wait(); } number++; System.out.println(Thread.currentThread().getName()+"No."+number); //Wake up other threads this.notifyAll(); } public synchronized void denumber() throws InterruptedException { while (number!=1){ this.wait(); } number--; System.out.println(Thread.currentThread().getName()+number); this.notifyAll(); } }
***Note that false wake-up occurs with if judgment
So the judgement is a while loop