多线程常用方法
线程停止
-
JDK提供的stop()、destroy() ->已废弃,不推荐
-
线程自己停下来
- 利用次数
- 标志位
标志位示例:
public class ThreadStopDemo {
public static void main(String[] args) throws InterruptedException {
ThreadStop threadStop = new ThreadStop();
new Thread(threadStop, "a").start();
TimeUnit.SECONDS.sleep(2);
threadStop.stop();
}
}
class ThreadStop implements Runnable {
private boolean flag = true;
@Override
public void run() {
while(flag) {
System.out.println(Thread.currentThread().getName() + "线程正在执行!");
}
}
/**
* 提供一个方法改变flag为false,来停止线程
*/
public void stop() {
this.flag = false;
System.out.println("线程停止");
}
}
线程休眠
sleep()方法
Thread.sleep(1000);
TimeUnit.SECONDS.sleep(1);
-
异常抛出
-
sleep时间达到后,线程进入就绪状态
-
sleep可以模拟网络延时、倒计时
-
每个对象都会有一把锁,sleep不会释放锁
模拟网络延时
// 模拟网络延时
public class ThreadSleep {
/*
1. sleep()结束后,线程进入就绪状态
2. sleep()不会释放锁
3. sleep()需要捕获异常
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("开始售票");
BuyTicketThread buyTicketThread = new BuyTicketThread();
new Thread(buyTicketThread, "张三").start();
new Thread(buyTicketThread, "李四").start();
new Thread(buyTicketThread, "王五").start();
}
}
class BuyTicketThread implements Runnable {
private Integer ticketNum = 20;
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
while (ticketNum > 0) {
System.out.println(Thread.currentThread().getName() + "买到第" + ticketNum-- + "张票");
}
}
}
线程礼让
- 让当前正在执行的线程暂停但不阻塞
- 将线程从运行状态转为阻塞状态
- CPU重新调度,礼让不一定成功。
不礼让测试代码:
public class ThreadYield {
public static void main(String[] args) throws InterruptedException {
YieldA yieldA = new YieldA();
YieldB yieldB = new YieldB();
new Thread(yieldA, "A").start();
new Thread(yieldB, "B").start();
}
}
class YieldA implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程正在执行");
System.out.println(Thread.currentThread().getName() + "线程结束执行");
}
}
class YieldB implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程正在执行");
System.out.println(Thread.currentThread().getName() + "线程结束执行");
}
}
输出结果:
线程礼让测试:
class YieldA implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程正在执行");
Thread.yield();
System.out.println(Thread.currentThread().getName() + "线程结束执行");
}
}
class YieldB implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程正在执行");
System.out.println(Thread.currentThread().getName() + "线程结束执行");
}
}
输出结果:
线程礼让成功
线程强制执行-Join
thread.join() 强制执行thread,当thread执行结束后,其他线程其继续执行。
(插队)
正常的多线程测试:
public class ThreadJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
public static void main(String[] args) {
Runnable target;
Thread thread = new Thread(new ThreadJoin(), "A");
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程:" + i);
}
}
}
执行结果:
主线程:0
主线程:1
主线程:2
主线程:3
主线程:4
A:0
主线程:5
主线程:6
主线程:7
主线程:8
主线程:9
主线程:10
主线程:11
主线程:12
A:1
主线程:13
主线程:14
主线程:15
主线程:16
主线程:17
A:2
主线程:18
A:3
主线程:19
A:4
主线程:20
主线程:21
A:5
... ...
可以看到线程A与主线程交替执行。
在主线程中添加代码thread.join();
public class ThreadJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
public static void main(String[] args) throws InterruptedException {
Runnable target;
Thread thread = new Thread(new ThreadJoin(), "A");
thread.start();
for (int i = 0; i < 100; i++) {
if (i == 20) {
thread.join();
}
System.out.println("主线程:" + i);
}
}
}
执行结果:
主线程:1
主线程:2
主线程:3
主线程:4
主线程:5
主线程:6
主线程:7
A:0
A:1
A:2
A:3
A:4
A:5
A:6
主线程:8
主线程:9
... ...
// i == 20
主线程:19
A:10
A:11
A:12
... ...
A:48
A:49
在i==20之前,线程A与main线程交替执行,当i==20是,强制A线程执行结束。