1、进程、线程
进程:操作系统分配资源的最小单位
线程:操作系统调动的最小单位
2、使用多线程
-
继承
Thread类例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); } } class MyThread extends Thread { @Override public void run() { super.run(); System.out.println("thread running"); } }输出:
thread running
缺点:不支持多继承
-
实现
Runnable接口例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread myThread = new MyThread(); Thread thread = new Thread(myThread); thread.start(); } } class MyThread implements Runnable { @Override public void run() { System.out.println("thread running"); } }输出:
thread running
优点:“间接”支持多继承
-
分析多线程的命令
- jps+jstack.exe
- jmc.exe(推荐)
- jvisualvm.exe
3、currentThread() 方法
作用:当前代码块正在被哪个线程调用
例子:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
thread.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println(currentThread().getName());
}
}
输出:
Thread-0
4、isAlive() 方法
作用:当前线程是否处于活动状态(正在运行、准备开始运行)
例子:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
System.out.println("start->" + thread.isAlive());
thread.start();
Thread.sleep(100);
System.out.println("end->" + thread.isAlive());
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("run->" + isAlive());
}
}
输出:
start->false
run->true
end->false
5、sleep(long millis) 方法和sleep(long millis, int nanos) 方法
作用:在指定的时间内(毫秒/毫秒+纳秒)内让“正在执行的线程”休眠,正在执行的线程指 this.currentThread() 返回的线程
例子:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
thread.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("start time->"+System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end time-> "+System.currentTimeMillis());
}
}
输出:
start time->1637762721620
end time-> 1637762723623
6、getId() 方法
作用:获得线程的唯一标识
例子:
public class Run {
public static void main(String[] args) throws InterruptedException {
Thread thread = Thread.currentThread();
System.out.println(thread.getId());
}
}
输出:
1
7、停止线程
-
判断线程是否为停止状态
-
public boolean isInterrupted()作用:测试
currentThread()是否已经中断,不清除状态标志例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(100); thread.interrupt(); System.out.println("is thread stop:"+thread.isInterrupted()); System.out.println("is thread stop:"+thread.isInterrupted()); System.out.println("end"); } } class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 1000; i++) { System.out.println("i=" + i); } } }输出:
i=755
i=756
is thread stop:true
is thread stop:true
i=757
i=758 -
public static boolean interrupted()作用:测试
this关键字所在的类是否已经中断,执行后具有清除状态标志为 false 的功能例子:
public class Run { public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt(); System.out.println("is thread stop:" + Thread.interrupted()); System.out.println("is thread stop:" + Thread.interrupted()); System.out.println("end"); } }输出:
is thread stop:true
is thread stop:false
end第二次输出 false 的原因:
interrupted()具有清除状态的功能,第一次调用时,打印了当前线程被中断,然后将状态清除,此时当前线程的状态为不中断;在第二次调用时,由于上次的调用原因,此时的线程状态已经是不中断,所以打印为 false
-
-
异常法停止线程
例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(100); thread.interrupt(); } } class MyThread extends Thread { @Override public void run() { super.run(); try { for (int i = 0; i < 2000; i++) { if (Thread.interrupted()) { System.out.println("already stop,exit"); throw new InterruptedException(); } System.out.println("i=" + i); } System.out.println("end"); } catch (InterruptedException e) { System.out.println("enter exception"); } } }输出:
i=686
i=687
already stop,exit
enter exception -
stop()法暴力停止线程例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(50); thread.stop(); } } class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 1000; i++) { System.out.println("i=" + i); } } }输出:
i=374
i=375
i=376
i=377
i=378缺点:
stop()会释放锁导致数据不一致,已被弃用 -
return法停止线程例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(50); thread.interrupt(); } } class MyThread extends Thread { @Override public void run() { while (true) { if (this.isInterrupted()) { System.out.println("stop"); return; } System.out.println(System.currentTimeMillis()); } } }输出:
1637766071932
1637766071932
1637766071932
stop -
在
sleep状态下停止线程不管调用顺序,只要
interrupt()与stop()碰到一起就会出现异常例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(200); thread.interrupt(); } } class MyThread extends Thread { @Override public void run() { try { System.out.println("thread begin"); Thread.sleep(20000); System.out.println("thread end"); } catch (InterruptedException e) { e.printStackTrace(); } } }输出:
thread begin
java.lang.InterruptedException: sleep interrupted
at java.base/java.lang.Thread.sleep(Native Method)
at demo.MyThread.run(Run.java:18)
8、暂停线程
-
suspend()与resume()的使用例子:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(5000); thread.suspend(); System.out.println("A=" + System.currentTimeMillis() + " i=" + thread.getI()); Thread.sleep(5000); System.out.println("A=" + System.currentTimeMillis() + " i=" + thread.getI()); thread.resume(); Thread.sleep(5000); thread.suspend(); System.out.println("B=" + System.currentTimeMillis() + " i=" + thread.getI()); Thread.sleep(5000); System.out.println("B=" + System.currentTimeMillis() + " i=" + thread.getI()); } } class MyThread extends Thread { private long i = 0; public long getI() { return i; } public void setI(long i) { this.i = i; } @Override public void run() { while (true) { i++; } } }输出:
A=1637855269659 i=8483654775
A=1637855274661 i=8483654775
B=1637855279666 i=17266749694
B=1637855284669 i=17266749694 -
suspend()与resume()的缺点- 独占
- 数据不完成
-
suspend()与resume()的替代suspend()->wait()resume()->notify()/notifyAll()
9、yield() 方法
作用:放弃当前的 CPU 资源,让其他任务去占用 CPU 时间片
例子:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
thread.start();
MyThreadYield threadYield=new MyThreadYield();
threadYield.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
}
long endTime = System.currentTimeMillis();
System.out.println("time:" + (endTime - beginTime));
}
}
class MyThreadYield extends Thread {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
Thread.yield();
}
long endTime = System.currentTimeMillis();
System.out.println("time:" + (endTime - beginTime));
}
}
输出:
time:1
time:24
10、线程的优先级
设置优先级 public final void setPriority(int newPriority)
预定三个优先级:
/**
* The minimum priority that a thread can have.
*/
public static final int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public static final int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public static final int MAX_PRIORITY = 10;
优先级具有继承性,例如A线程启动B线程,则B的优先级和A一样
11、守护线程
Java中存在两种线程:用户线程(非守护线程)、守护线程
只有进程中不存在非守护线程,则守护线程自动销毁;若存在任何一个非守护线程,守护线程就要继续工作
主线程(main)属于非守护线程
设置守护线程:setDaemon(true),需要在 start() 方法前设置
例子:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
thread.setDaemon(true);
thread.start();
Thread.sleep(5000);
System.out.println("exit");
}
}
class MyThread extends Thread {
@Override
public void run() {
int i = 0;
while (true) {
i++;
System.out.println("i=" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出:
i=1
i=2
i=3
i=4
i=5
exit