当前位置:网站首页>Common thread methods and daemon threads
Common thread methods and daemon threads
2022-07-01 04:01:00 【Sit at a sunny window and drink tea alone】
Common methods
Method name | static | Functional specifications | Be careful |
---|---|---|---|
start() | Start a new thread , Run in a new thread run The code in the method | start The method is simply to put the thread into ready , The code doesn't have to run immediately (CPU I haven't given it a time slice yet ). Per thread object start Method can only be called once , If called more than once, it will appear IllegalThreadStateException | |
run() | The method that will be called after the new thread starts | If in construction Thread Object Runnable Parameters , Called after the thread starts Runnable Medium run Method , Otherwise, no operation will be performed by default . But it can be created Thread Subclass object of , To override the default behavior | |
join() | Wait for the thread to finish running | ||
join(long n) | Wait for the thread to finish running , Waiting for the most n millisecond | ||
getId() | Get thread length integer id | id only | |
getName() | Get the thread name | ||
setName(String) | Modify the thread name | ||
getPriority() | Get thread priority | ||
setPriority(int) | Modify thread priority | java The thread priority specified in is 1~10 The integer of , A higher priority can improve the thread's performance CPU Scheduling probability | |
getState() | Get thread status | Java Thread status in 6 individual enum Express , Respectively :NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED | |
isInterrupted() | Judge whether it is interrupted | It won't clear Break mark | |
isAlive() | Is the thread alive ( Not finished yet ) | ||
interrupt() | Interrupt thread | If the interrupted thread is sleep,wait,join It will cause the interrupted thread to throw InterruptedException, And clear the break mark ; If you interrupt a running thread , Will set up Break mark ;park Thread interrupted , Break marks will also be set | |
interrupted() | static | Determine whether the current thread is interrupted | Will clear Break mark |
currentThread() | static | Get the currently executing thread | |
sleep(long n) | static | static Hibernate the currently executing thread n millisecond , Give up when dormant cpu Time slice to other threads | |
yield() | static | Prompt the thread scheduler to give up the current thread pair CPU Use | Mainly for testing and debugging |
start And run
start The method is simply to put the thread into ready , The code doesn't have to run immediately (CPU I haven't given it a time slice yet ). Per thread object start Method can only be called once , If called more than once, it will appear IllegalThreadStateException
Test code :
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.io.FileReader;
/** * @author Wang Tianci * @title: TestStartAndRun * @projectName hm-juc-codes * @description: test start And run Method * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-21 15:13 */
@Slf4j(topic = "c.TestStartAndRun")
@SuppressWarnings("all")
public class TestStartAndRun {
/** * Analog read */
public static void reader() {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < 10000_000_00; i++) {
sum += sum;
}
long end = System.currentTimeMillis();
log.debug("reader cost {} ms ... ", (end - start));
}
public static void main(String[] args) {
Thread t1 = new Thread("t1") {
@Override
public void run() {
// Get the name of the current thread
log.debug("{} running ... ", Thread.currentThread().getName());
reader();
}
};
t1.start();
log.debug("do other thing ... ");
}
}
Running results
C:\dev\Java\jdk1.8.0_152\bin\java.exe -javaagent:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=6195:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\dev\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\rt.jar;F:\JavaCode\hm-juc-codes\juc-case-01\target\classes;F:\MavenRepo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\MavenRepo\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\MavenRepo\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\MavenRepo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;F:\MavenRepo\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;F:\MavenRepo\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;F:\MavenRepo\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;F:\MavenRepo\org\openjdk\jmh\jmh-java-benchmark-archetype\1.35\jmh-java-benchmark-archetype-1.35.jar cn.knightzz.example.e2.method.TestStartAndRun
16:07:46.045 [main] DEBUG c.TestStartAndRun - do other thing ...
16:07:46.045 [t1] DEBUG c.TestStartAndRun - t1 running ...
16:07:46.301 [t1] DEBUG c.TestStartAndRun - reader cost 254 ms ...
Process finished with exit code 0
As shown in the above running results :
t1
The thread does not execute immediately after it is started , Instead, it executes the method of the main thread , After thatt1
Thread method- Be careful
running
yes t1 thread-executed ! - t1 Threads and main threads execute in parallel !
While using run
Execution time , running
yes stay Executed by the main thread , There is no new thread !
Code instance :
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.TestStartStatus")
@SuppressWarnings("all")
public class TestStartStatus {
public static void main(String[] args) {
Thread t1 = new Thread("t1") {
@Override
public void run() {
// Get the name of the current thread
log.debug("{} running ... ", Thread.currentThread().getName());
}
};
log.debug("t1 : {} " , t1.getState());
t1.start();
log.debug("t1 : {} " , t1.getState());
}
}
Execution results :
C:\dev\Java\jdk1.8.0_152\bin\java.exe -javaagent:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=14539:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\dev\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\rt.jar;F:\JavaCode\hm-juc-codes\juc-case-01\target\classes;F:\MavenRepo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\MavenRepo\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\MavenRepo\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\MavenRepo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;F:\MavenRepo\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;F:\MavenRepo\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;F:\MavenRepo\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;F:\MavenRepo\org\openjdk\jmh\jmh-java-benchmark-archetype\1.35\jmh-java-benchmark-archetype-1.35.jar cn.knightzz.example.e2.method.TestStartStatus
17:28:18.600 [main] DEBUG c.TestStartStatus - t1 : NEW
17:28:18.604 [main] DEBUG c.TestStartStatus - t1 : RUNNABLE
17:28:18.604 [t1] DEBUG c.TestStartStatus - t1 running ...
Process finished with exit code 0
You can see the above execution results and code , When executed start()
After method , The state of the thread changes from NEW
Turned into RUNNABLE
summary :
- Call directly run It is executed in the main thread run, No new thread started
- Use start Is to start a new thread , Indirect execution through new threads run The code in
sleep And yield
sleep
- call sleep Will cause the current thread to
Running
Get intoTimed Waiting
state ( Blocking ) - The current thread can use
interrupt
Method to interrupt the sleeping thread , At this time sleep Method will throwInterruptedException
- After sleep, the thread may not be executed immediately
- Suggest using
TimeUnit
Ofsleep
Instead ofThread
Ofsleep
For better readability
sleep state
Code example :
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.TestSleep")
@SuppressWarnings("all")
public class TestSleep {
public static void main(String[] args){
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug("t1 running ... ");
log.debug("into sleep ... ");
// The current thread sleeps
try {
Thread.sleep(100);
} catch (InterruptedException e) {
log.debug("t1 wake up ... ");
throw new RuntimeException(e);
}
}
};
log.debug("t1 status is {} ... " , t1.getState());
t1.start();
log.debug("t1 status is {} ... " , t1.getState());
// Interrupt other sleeping threads
log.debug("do other things ... ");
}
}
C:\dev\Java\jdk1.8.0_152\bin\java.exe -javaagent:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=6691:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\dev\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\rt.jar;F:\JavaCode\hm-juc-codes\juc-case-01\target\classes;F:\MavenRepo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\MavenRepo\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\MavenRepo\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\MavenRepo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;F:\MavenRepo\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;F:\MavenRepo\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;F:\MavenRepo\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;F:\MavenRepo\org\openjdk\jmh\jmh-java-benchmark-archetype\1.35\jmh-java-benchmark-archetype-1.35.jar cn.knightzz.example.e2.method.TestSleep
20:01:43.076 [main] DEBUG c.TestSleep - t1 status is NEW ...
20:01:43.079 [main] DEBUG c.TestSleep - t1 status is RUNNABLE ...
20:01:43.079 [main] DEBUG c.TestSleep - do other things ...
20:01:43.079 [t1] DEBUG c.TestSleep - t1 running ...
20:01:43.079 [t1] DEBUG c.TestSleep - into sleep ...
Process finished with exit code 0
figure
The reason for the main thread to sleep is because prevent t1
The thread is not sleeping yet , t1
The status information of the thread has been printed out , here t1
The state of the thread is still RUNNABLE
sleep interrupt
Code example :
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
/** * @author Wang Tianci * @title: TestInterceptor * @projectName hm-juc-codes * @description: test sleep interrupt * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-21 20:39 */
@Slf4j(topic = "c.TestSleep")
@SuppressWarnings("all")
public class TestInterceptor {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug("t1 running ... ");
// The current thread sleeps
try {
log.debug("start sleep ... ");
Thread.sleep(2000);
} catch (InterruptedException e) {
log.debug("t1 wake up ... ");
throw new RuntimeException(e);
}
}
};
t1.start();
// The main thread sleep is to ensure that t1 Thread executing interrupt Method is already sleeping
Thread.sleep(1000);
t1.interrupt();
log.debug("do other things ... ");
}
}
C:\dev\Java\jdk1.8.0_152\bin\java.exe -javaagent:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=6365:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\dev\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\rt.jar;F:\JavaCode\hm-juc-codes\juc-case-01\target\classes;F:\MavenRepo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\MavenRepo\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\MavenRepo\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\MavenRepo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;F:\MavenRepo\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;F:\MavenRepo\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;F:\MavenRepo\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;F:\MavenRepo\org\openjdk\jmh\jmh-java-benchmark-archetype\1.35\jmh-java-benchmark-archetype-1.35.jar cn.knightzz.example.e2.method.TestInterceptor
20:51:30.022 [t1] DEBUG c.TestSleep - t1 running ...
20:51:30.024 [t1] DEBUG c.TestSleep - start sleep ...
20:51:31.023 [t1] DEBUG c.TestSleep - t1 wake up ...
20:51:31.023 [main] DEBUG c.TestSleep - do other things ...
Exception in thread "t1" java.lang.RuntimeException: java.lang.InterruptedException: sleep interrupted
at cn.knightzz.example.e2.method.TestInterceptor$1.run(TestInterceptor.java:30)
Caused by: java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at cn.knightzz.example.e2.method.TestInterceptor$1.run(TestInterceptor.java:27)
The running result is as above , You can see , t1
The thread is sleeping 1s
in the future , He was interrupted
TimeUnit Sleep
Increase readability
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import javax.swing.*;
import java.util.concurrent.TimeUnit;
/** * @author Wang Tianci * @title: TestUnit * @projectName hm-juc-codes * @description: test TimeUnit * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-21 20:59 */
@Slf4j(topic = "c.TestTimeUnit")
@SuppressWarnings("all")
public class TestTimeUnit {
public static void main(String[] args) throws InterruptedException {
log.debug("start ...");
TimeUnit.SECONDS.sleep(10);
// Thread.sleep()
log.debug("end ...");
}
}
yield
- call yield Will cause the current thread to
Running
Get intoRunnable
Ready state , Then schedule other threads. - The specific implementation depends on the task scheduler of the operating system
- The purpose is to put the current thread CPU Let the executive power go , however CPU Next time, you may give the time slice to
Thread priority
- Thread priority will prompt (hint) The scheduler schedules the thread first , But it's just a hint , The scheduler can ignore it
- If cpu Busy , The thread with higher priority will get more timeslices , but cpu Leisure time , Priority has little effect
CPU Idle situation
Code example :
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
/** * @author Wang Tianci * @title: TestPriority * @projectName hm-juc-codes * @description: Test process priority * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-22 20:33 */
@SuppressWarnings("all")
@Slf4j(topic = "c.TestPriority")
public class TestPriority {
public static void main(String[] args) {
Runnable task1 = new Runnable() {
@Override
public void run() {
log.debug("task1 running ... ");
}
};
Runnable task2 = new Runnable() {
@Override
public void run() {
log.debug("task2 running ... ");
}
};
Thread t1 = new Thread(task1, "t1");
Thread t2 = new Thread(task2, "t1");
// set priority
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
log.debug("main ended ... ");
}
}
C:\dev\Java\jdk1.8.0_152\bin\java.exe -javaagent:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=8641:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\dev\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\rt.jar;F:\JavaCode\hm-juc-codes\juc-case-01\target\classes;F:\MavenRepo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\MavenRepo\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\MavenRepo\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\MavenRepo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;F:\MavenRepo\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;F:\MavenRepo\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;F:\MavenRepo\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;F:\MavenRepo\org\openjdk\jmh\jmh-java-benchmark-archetype\1.35\jmh-java-benchmark-archetype-1.35.jar cn.knightzz.example.e2.method.TestPriority
20:38:32.626 [main] DEBUG c.TestPriority - main ended ...
20:38:32.626 [t1] DEBUG c.TestPriority - task2 running ...
20:38:32.626 [t1] DEBUG c.TestPriority - task1 running ...
Process finished with exit code 0
You can see , The results of the above run : Even though t1
The thread sets the maximum priority , But it will still appear t2
The thread runs first
CPU A busy situation
however If When the thread is busy :
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
/** * @author Wang Tianci * @title: TestPriority * @projectName hm-juc-codes * @description: Test process priority * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-22 20:33 */
@SuppressWarnings("all")
@Slf4j(topic = "c.TestPriority")
public class TestPriority {
public static void main(String[] args) {
Runnable task1 = new Runnable() {
@Override
public void run() {
// log.debug("task1 running ... ");
int count = 0;
while (true) {
Thread.yield();
log.debug("task1 ==================> {}", count);
count++;
}
}
};
Runnable task2 = new Runnable() {
@Override
public void run() {
int count = 0;
while (true) {
Thread.yield();
log.debug("task2 ==================> {}", count);
count++;
}
}
};
Thread t1 = new Thread(task1, "t1");
Thread t2 = new Thread(task2, "t1");
// set priority
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
log.debug("main ended ... ");
}
}
As can be seen above , task1 The number of is higher than task2 The number is big , explain task1
obtain CPU There are many times of time slice
join Methods,
join
Method waits for the corresponding thread to end , such as t1.join()
The effect is to wait t1 Thread end
Case study 1 General situation
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("all")
@Slf4j(topic = "c.TestJoin")
public class TestJoin {
private static int value = 0;
public static void main(String[] args) throws InterruptedException {
method1();
}
private static void method1() throws InterruptedException {
log.debug("method1 start ... ");
Thread t1 = new Thread(() -> {
try {
log.debug("sleep start ... ");
TimeUnit.SECONDS.sleep(1);
value = 10;
log.debug("sleep end ... ");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
log.debug("value result {} ", value);
log.debug("main end ... ");
}
}
C:\dev\Java\jdk1.8.0_152\bin\java.exe -javaagent:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=5463:D:\DevApp\JetBrain\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\dev\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\dev\Java\jdk1.8.0_152\jre\lib\rt.jar;F:\JavaCode\hm-juc-codes\juc-case-01\target\classes;F:\MavenRepo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\MavenRepo\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\MavenRepo\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\MavenRepo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;F:\MavenRepo\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;F:\MavenRepo\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;F:\MavenRepo\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;F:\MavenRepo\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;F:\MavenRepo\org\openjdk\jmh\jmh-java-benchmark-archetype\1.35\jmh-java-benchmark-archetype-1.35.jar cn.knightzz.example.e2.method.TestJoin
21:56:45.562 [main] DEBUG c.TestJoin - method1 start ...
21:56:45.594 [Thread-0] DEBUG c.TestJoin - sleep start ...
21:56:45.594 [main] DEBUG c.TestJoin - value result 0
21:56:45.595 [main] DEBUG c.TestJoin - main end ...
21:56:46.606 [Thread-0] DEBUG c.TestJoin - sleep end ...
Process finished with exit code 0
You can see the results above , Output value
The value is 0, This is because the main thread and t1
Threads execute in parallel , There is no such thing as who waits
Case study 2 join
We can use join To wait for the thread to end
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("all")
@Slf4j(topic = "c.TestJoin")
public class TestJoin {
private static int value = 0;
public static void main(String[] args) throws InterruptedException {
method1();
}
private static void method1() throws InterruptedException {
log.debug("method1 start ... ");
Thread t1 = new Thread(() -> {
try {
log.debug("sleep start ... ");
TimeUnit.SECONDS.sleep(1);
value = 10;
log.debug("sleep end ... ");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
t1.join();
log.debug("value result {} ", value);
log.debug("main end ... ");
}
}
From the caller's point of view :
- Need to wait for the result to return , What can be continued is Sync
- What you can continue to execute without waiting for the result to return is asynchronous
Case study 3 join Method
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("all")
@Slf4j(topic = "c.TestJoin2")
public class TestJoin2 {
private static int value = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(){
@Override
public void run() {
try {
// sleep 1s
TimeUnit.SECONDS.sleep(1);
// modify value Value
value = 10;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
Thread t2 = new Thread(){
@Override
public void run() {
try {
// sleep 1s
TimeUnit.SECONDS.sleep(2);
// modify value Value
value = 20;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("value : {} " , value);
log.debug("do other thing ... ");
}
}
ask : The execution time of the above code is 3s still 2s ?
Case study 4 Time limited join
We can specify the waiting time by specifying the incoming parameters : t1.join(3000);
package cn.knightzz.example.e2.method;
import cn.knightzz.example.e1.test.Test2;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("all")
@Slf4j(topic = "c.TestJoin2")
public class TestJoin3 {
static int value = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(){
@Override
public void run() {
// sleep 5s
try {
TimeUnit.SECONDS.sleep(5);
value = 10;
log.debug("sleep end ... ");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
t1.start();
log.debug("thread start ... ");
t1.join(3000);
log.debug("value : {}", value);
log.debug("join end ... ");
}
}
C:\Dev\jdk8\bin\java.exe -javaagent:D:\DevApp\JetBrains\ToolBox\apps\IDEA-U\ch-0\221.5787.30\lib\idea_rt.jar=4754:D:\DevApp\JetBrains\ToolBox\apps\IDEA-U\ch-0\221.5787.30\bin -Dfile.encoding=UTF-8 -classpath C:\Dev\jdk8\jre\lib\charsets.jar;C:\Dev\jdk8\jre\lib\ext\access-bridge-64.jar;C:\Dev\jdk8\jre\lib\ext\cldrdata.jar;C:\Dev\jdk8\jre\lib\ext\dnsns.jar;C:\Dev\jdk8\jre\lib\ext\dtfj.jar;C:\Dev\jdk8\jre\lib\ext\dtfjview.jar;C:\Dev\jdk8\jre\lib\ext\jaccess.jar;C:\Dev\jdk8\jre\lib\ext\localedata.jar;C:\Dev\jdk8\jre\lib\ext\nashorn.jar;C:\Dev\jdk8\jre\lib\ext\sunec.jar;C:\Dev\jdk8\jre\lib\ext\sunjce_provider.jar;C:\Dev\jdk8\jre\lib\ext\sunmscapi.jar;C:\Dev\jdk8\jre\lib\ext\sunpkcs11.jar;C:\Dev\jdk8\jre\lib\ext\traceformat.jar;C:\Dev\jdk8\jre\lib\ext\zipfs.jar;C:\Dev\jdk8\jre\lib\jce.jar;C:\Dev\jdk8\jre\lib\jsse.jar;C:\Dev\jdk8\jre\lib\management-agent.jar;C:\Dev\jdk8\jre\lib\resources.jar;C:\Dev\jdk8\jre\lib\rt.jar;C:\Dev\jdk8\bin\Dll02.dll;K:\CodeSpace\HMCodeSpace\hm-juc-codes\juc-case-01\target\classes;D:\Repos\mavenRepos\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;D:\Repos\mavenRepos\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;D:\Repos\mavenRepos\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;D:\Repos\mavenRepos\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;D:\Repos\mavenRepos\cn\hutool\hutool-all\5.7.20\hutool-all-5.7.20.jar;D:\Repos\mavenRepos\org\openjdk\jmh\jmh-core-benchmarks\1.35\jmh-core-benchmarks-1.35.jar;D:\Repos\mavenRepos\org\openjdk\jmh\jmh-core\1.35\jmh-core-1.35.jar;D:\Repos\mavenRepos\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;D:\Repos\mavenRepos\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar cn.knightzz.example.e2.method.TestJoin3
21:16:55.011 [main] DEBUG c.TestJoin2 - thread start ...
21:16:58.017 [main] DEBUG c.TestJoin2 - value : 0
21:16:58.019 [main] DEBUG c.TestJoin2 - join end ...
21:17:00.015 [Thread-3] DEBUG c.TestJoin2 - sleep end ...
Process finished with exit code 0
As can be seen above
interrupt Methods,
interrupt sleep, wait, join The thread of
sleep, wait, join
These methods will put the thread into a blocking state , interrupt sleep The thread of , The interrupt status is cleared ( The interrupt status is reset to false
), With sleep
For example
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
/** * @author Wang Tianci * @title: TestInterrupt * @projectName hm-juc-codes * @description: interrupt sleep Threads * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-27 21:37 */
@SuppressWarnings("all")
@Slf4j(topic = "c.TestInterrupt")
public class TestInterrupt {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5); // sleep, wait, join After being interrupted , The break mark will be cleared
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, "t1");
t1.start();
// Main thread sleep 1s , Ensure that when interrupted , t1 The thread has sleep
TimeUnit.SECONDS.sleep(1);
// interrupt
t1.interrupt();
// Check the interruption status
log.debug(" Break mark : {}" , t1.isInterrupted());
}
}
As can be seen above , t1
The thread is interrupted during sleep , And the break flag is reset to false
t1.isInterrupted()
If the thread has been interrupted, return true
, Otherwise return to false
, Interrupted threads in sleep will throw exceptions
Interrupt a normal thread
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
/** * @author Wang Tianci * @title: TestInterrupt2 * @projectName hm-juc-codes * @description: Test interrupts normal threads * @website <a href="http://knightzz.cn/">http://knightzz.cn/</a> * @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a> * @create: 2022-06-28 14:45 */
@SuppressWarnings("all")
@Slf4j(topic = "c.TestInterrupt2")
public class TestInterrupt2 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while(true) {
Thread thread = Thread.currentThread();
boolean interrupted = thread.isInterrupted();
if (interrupted) {
log.debug(" Interrupt state : {} " , interrupted);
break;
}
}
}, "t1");
t1.start();
// Sleep for a second , Guarantee t1 The thread is running
TimeUnit.SECONDS.sleep(1);
t1.interrupt();
}
}
As can be seen above : The normal thread is interrupted while running , The interrupt status is true
The two phases of the model terminate
problem
- In a thread t1 Interrupt the thread correctly t2 , And let t2 Threads have a way to handle interrupts
Wrong thinking
Using thread objects stop() Method to stop the thread
stop
Method will really kill the thread , If the thread locks the shared resource , Then when it is killed, it will never have a chance to release the lock , Other threads will never acquire locks
Use System.exit(int) Method to stop the thread
- The purpose is only to stop a thread , But this will stop the whole process
Two stage termination mode
https://blog.csdn.net/thetimelyrain/article/details/114587111
LockSupport.park()
You can make the current thread block
package cn.knightzz.example.e2.method;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
@SuppressWarnings("all")
@Slf4j(topic = "c.TestInterrupt2")
public class TestPark {
public static void main(String[] args) throws InterruptedException {
method1();
}
private static void method1() throws InterruptedException {
Thread t1 = new Thread(() -> {
log.debug("thread park ... ");
LockSupport.park(); // Pause current thread
log.debug("thread unpark ... ");
log.debug(" Interrupt state : {} " , Thread.currentThread().isInterrupted());
}, "t1");
t1.start();
// sleep 1s
TimeUnit.SECONDS.sleep(1);
// interrupt t1 Thread park
t1.interrupt();
}
}
You can see the above running results , Main thread sleep 1s
in the future , Start interrupting
LockSupport.park();
Method details :
- First execution park After being interrupted , isInterrupted Will turn into true
- here , If called again park() Method cannot block the thread .
private static void method1() throws InterruptedException {
Thread t1 = new Thread(() -> {
log.debug("thread park ... ");
LockSupport.park(); // Pause current thread
log.debug("thread unpark ... ");
log.debug(" Interrupt state : {} " , Thread.currentThread().isInterrupted());
// park() Method details :
// 1. First execution park After being interrupted , isInterrupted Will turn into true
// 2. here , If called again park() Method cannot block the thread .
LockSupport.park();
log.debug("thread unpark ... ");
}, "t1");
t1.start();
// sleep 1s
TimeUnit.SECONDS.sleep(1);
// interrupt t1 Thread park
t1.interrupt();
}
As can be seen above , When the thread is interrupted , Call again park
Method cannot block a thread
- have access to Thread.interrupted() Clear break status
private static void method1() throws InterruptedException {
Thread t1 = new Thread(() -> {
log.debug("thread park ... ");
LockSupport.park(); // Pause current thread
log.debug("thread unpark ... ");
log.debug(" Interrupt state : {} " , Thread.currentThread().isInterrupted());
// park() Method details :
// 1. First execution park After being interrupted , isInterrupted Will turn into true
// 2. here , If called again park() Method cannot block the thread .
LockSupport.park();
log.debug("thread unpark ... ");
// Clear break status
log.debug("clear interrupt status ... ");
Thread.currentThread().interrupted();
log.debug("thread park ... ");
LockSupport.park();
log.debug("thread unpark ... ");
}, "t1");
t1.start();
// sleep 1s
TimeUnit.SECONDS.sleep(1);
// interrupt t1 Thread park
t1.interrupt();
}
As can be seen above , After clearing the interrupt state , Call again park()
Method , here Thread blocked
LockSupport.park summary
LockSupport.park()
Used to block the current thread , And can beinterrupt()
Method break- First execution park After being interrupted , isInterrupted Will turn into true
- here , If called again park() Method cannot block the thread .
- But we can call
Thread.currentThread().interrupted();
Clear thread break status
Not recommended
Methods not recommended , These methods are outdated , Easy to break synchronous code blocks , Cause thread deadlock :
- stop() Stop the thread running
- suspend() Hang up ( Pause ) Thread running
- resume() Thread recovery
Main thread and guardian thread
By default ,Java process You need to wait for all threads to finish running , It's over . There is a special thread called the guardian thread , As long as other non daemon threads run , Even if the code of the daemon thread is not finished , It'll be forced to end .
package cn.knightzz.example.e2.thread;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("all")
@Slf4j(topic = "c.TestDaemon")
public class TestDaemon {
public static void main(String[] args) throws InterruptedException {
method1();
TimeUnit.SECONDS.sleep(1);
log.debug("main end ... ");
}
private static void method1() {
Thread t1 = new Thread(() -> {
log.debug("thread start ... ");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("thread end ... ");
}, "t1");
// Set the current thread as the daemon thread
// Be a daemon thread , As long as other non daemon threads run , Even if the code of the daemon thread is not finished , It'll be forced to end
t1.setDaemon(true);
t1.start();
}
}
Pictured above , According to the code above When t1 After thread start Sleep 3s Will execute the end , But because of t1 The thread is set as a daemon thread , therefore
When main After the method is over , Even if t1 The thread did not end execution , But it was also forced to shut down
边栏推荐
- 【TA-霜狼_may-《百人计划》】1.1 渲染流水线
- Analyse et cas du modèle pageobject
- 72. 编辑距离
- Grid system in bootstrap
- 跳槽一次涨8k,5年跳了3次...
- Chen Yu (Aqua) - Safety - & gt; Cloud Security - & gt; Multicloud security
- Use of JMeter counters
- NFT: utilisez EIP - 2981 pour commencer un voyage de redevances NFT
- 8. 字符串转换整数 (atoi)
- 389. find a difference
猜你喜欢
Millet College wechat scanning code login process record and bug resolution
Review column - message queue
JMeter login failure, extracting login token, and obtaining token problem solving
Use of JMeter counters
分账技术赋能农贸市场,重塑交易管理服务效能
Libevent Library Learning
【TA-霜狼_may-《百人计划》】1.4 PC手机图形API介绍
谷粒学院微信扫码登录过程记录以及bug解决
431. 将 N 叉树编码为二叉树 DFS
Class and object finalization
随机推荐
【TA-霜狼_may-《百人计划》】1.1 渲染流水线
基于Unet的环路滤波
[TA frost wolf \u may- hundred people plan] 1.2.1 vector basis
bootsrap中的栅格系统
熊市下的Coinbase:亏损、裁员、股价暴跌
JD intelligent customer service Yanxi intention system construction and intention recognition technology introduction
[EI conference] 2022 international joint civil and Offshore Engineering Conference (jccme 2022)
【发送邮件报错】535 Error:authentication failed
“目标检测“+“视觉理解“实现对输入图像的理解
Its appearance makes competitors tremble. Interpretation of Sony vision-s 02 products
Web components series (VIII) -- custom component style settings
Appium fundamentals of automated testing - basic principles of appium
类和对象收尾
30. Concatenate substrings of all words
Visit the image URL stored by Alibaba cloud to preview the thumbnail directly on the web page instead of downloading it directly
205. isomorphic string
这可能是你进腾讯最后的机会了..
241. 为运算表达式设计优先级
LeetCode 1827. Increment array with minimal operation
Deep learning | rnn/lstm of naturallanguageprocessing