java threads and processes
process
- Concept: is the running program
- It is an independent unit for the system to allocate and call resources
- Each process has its own memory space and system resources
Thread
- Concept: A single sequential control flow in a process is an execution path
- Single thread: a process has only one execution path (in order)
- Multithreading: multiple execution paths
- Multithreaded example
- Minesweeper: One to control the time and the other to control the player's own order to sell tickets and deposit money, etc.
Multi-threaded implementation
- One: Inherit the Thread class (implemented through the interface later)
- Define a class MyThread inherits the Thread class
在MyThread类中重写run方法
(Distinguish code that can be executed by threads)- Create an object of the MyThread class
- Start thread
- important point
- Rewrite the run method, because this method encapsulates thread execution code,
直接调用它的话会被当成普通方法调用
- Need to call the
start方法
start thread, and then the run method of the thread is called by the JVM - When getting the thread name, if you want to get it in main,
Thread.currentThread().getName()
there are three ways to get the name 1. get set method (getName is directly equivalent to this.getName()), 2. structure with parameters, 3. static method currentThread() returns A reference to the current thread of execution
- Rewrite the run method, because this method encapsulates thread execution code,
package Thread;
public class ThreadName extends Thread{
ThreadName(String name){
super(name);//超类有这个带参构造则一定要传super的参数且为第一句
}
//@Override
public void run() {
for(int i=0;i<50;i++){
System.out.println(getName()+":"+i);
}
}
}
package Thread;
public class ThreadNameDemo{
public static void main(String[] args) {
ThreadName tn1=new ThreadName("线程1");//tn1.setName("线程1")
ThreadName tn2=new ThreadName("线程2");
tn1.start();
tn2.start();
//也可以在main函数中用getName方法,但是因为测试类没有继承Thread类,所以不可以直接用getName,需要用到Thread.currentThread().getName()
}
}
-
Two, thread scheduling
- Java uses a preemptive scheduling model: give priority to threads with high priority to use the CPU, if the threads have the same priority, then one will be randomly selected
但是优先级高并不一定就是一直先执行,只是该线程抢占到的CPU时间片的几率更大
, But you can see the desired effect only when there are more or more runs- The thread default value is 5, and the priority range is 1-10
public class ThreadPriorityDemo {
public static void main(String[] args) {
ThreadPriority tp1=new ThreadPriority();
ThreadPriority tp2=new ThreadPriority();
tp1.setName("线程1");
tp2.setName("线程2");
System.out.println(tp1.getPriority());
System.out.println(tp2.getPriority());
tp1.setPriority(1);
tp2.setPriority(10);
tp1.start();
tp2.start();
}
}
public final int getPriority():返回线程优先级
public final void setPriority():更改此线程的优先级
- Three, thread control
-
-
The join method allows the thread to complete execution before starting other threads
-
The representative methods of throwing InterruptedException (indicating that this method may take a little time, but it is a method that can be cancelled) are:
-
- java.lang.Object class
wait 方法
- java.lang.Object class
-
- java.lang.Thread class
sleep 方法
- java.lang.Thread class
-
- java.lang.Thread class
join 方法
- java.lang.Thread class
-
-
The thread executing the wait method will enter the waiting area and wait to be notified/notify All. During the waiting period, the thread will not be active.
The thread that executes the sleep method will
暂停执行参数内所设置的时间。
The thread executing the join method will wait until the specified thread ends.
public class ThreadSleep extends Thread{
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
try {
Thread.sleep(1000);//让当前正在执行的线程休眠1s(暂停执行),每次执行三者各执行一次,因为ts1抢到后执行run()休眠1次,ts2抢到后也休眠1次同时抢抢到后执行调用run才开始休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadJoinDemo {
public static void main(String[] args) {
ThreadJoin tj1=new ThreadJoin();
ThreadJoin tj2=new ThreadJoin();
ThreadJoin tj3=new ThreadJoin();
tj1.setName("开花");
tj2.setName("结果1");
tj3.setName("结果2");
tj1.start();
try {
tj1.join();//等待tj1执行完
} catch (InterruptedException e) {
e.printStackTrace();
}
tj2.start();
tj3.start();
}
}
public class ThreadDaemondemo {
public static void main(String[] args) {
ThreadDaemon td1=new ThreadDaemon();
ThreadDaemon td2=new ThreadDaemon();
td2.setName("士兵1");
td1.setName("士兵2");
//设置主线程为将军
Thread.currentThread().setName("将军");
//设置守护线程
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();//守护线程在主线程结束后很快执行完毕但是不是立即结束
for(int i=0;i<40;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
Although the main thread is automatically created when the program starts, it can be controlled by a Thread object. To do this, you have to call the method
currentThread()获得它的一个引用
, currentThread() isThread类的公有的静态成员。
- Three, the life cycle of the thread
-
-
So the previous sleep method is that it blocks after it runs once, and then goes back to grab the right of execution. Each of the three threads runs once and then goes back to grab, so there are three for one round.
-
- Other implementations of multithreading: (There are two ways to create a new thread of execution)
- One, classify
声明为 Thread 的子类
. The subclass should override the run method of the Thread class, and then you can allocate and start an instance of the subclass - 2. Statement
实现 Runnable 接口的类
. This class implements the run method. Then you can assign an instance of that class,在创建 Thread 时作为一个参数来传递并启动
- The previous examples are implemented in the first way, and then the second way
- The second way avoids the limitations of java single inheritance
- Define a class Myrunnable to implement the Runnable interface
- Override the run method in the MyRunnable class
- Create an object of the Myrunnable class
- Create a Thread object and pass the above object as a parameter to the Thread object
- Start thread
- Thread construction method
- One, classify
public class MyRunnable implements Runnable{
//Runnable接口和Thread类没有关系不能调用Thread中的getName方法
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class MyRunnableDemo {
public static void main(String[] args) {
MyRunnable mr=new MyRunnable();
Thread t1=new Thread(mr);//Thread t1=new Thread(mr,"线程1")
Thread t2=new Thread(mr);//Thread t2=new Thread(mr,"线程2")起名
t1.start();
t2.start();
}
}
Comprehensive case (mutual exclusion mechanism lock mechanism)
- Ticket sales
//第一次:出现两种问题负数票和一票多用,问题原因是线程执行的随机性
public void run() {
while(true){
if(ticket>0){
try {
Thread.sleep(100);//通过sleep模拟出票时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"张票");
//可能在ticket--之前t2或者t3抢到了CPU的执行权:这就是看到同一张票出现多次的原因
//可能在t1将ticket--变成0时,t1不能再继续售票,但t2已经进来循环了,所以还可以--:这就是出现负数票的原因
ticket--;
}
}
}
- The basis of the problem due to randomness: multi-threaded environment and shared data resources and multiple statement operations to share data
- Solve the problem: lock the code for multiple statements to operate and share data, so that there is only one thread at any time
- Synchronization code block:
synchronized(任意对象){多条语句操作共享数据的代码块}
(any object can be regarded as a lock)
- Synchronization code block:
public class SellTicket implements Runnable{
private int ticket=100;
private Object obj=new Object();//共用一把锁
@Override
public void run() {
while(true){
synchronized (obj){
//如果是t1先抢到执行权则t1执行到这里会把这段代码锁起来,t2、t3只能等即时t1休眠期直到t1出来代码块
if(ticket>0){
try {
Thread.sleep(100);//通过sleep模拟出票时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"张票");
ticket--;
}
}
}
}
}
- Synchronization advantages and disadvantages: solve the data security problem of multi-threading, but when there are many threads, each thread will judge the lock on synchronization, which consumes resources and reduces operating efficiency
- Synchronization method:
修饰符 sychronized 返回值类型 方法名(方法参数){}
- Synchronous static method:
修饰符 static sychronized 返回值类型 方法名(方法参数){}
- The locked object in the synchronization method is this (if it is a static method, you need to replace this with the class name.class)