线程休眠:sleep
public static void sleep(long millis)throws InterruptedException
设置休眠的毫秒数,一到时间自动唤醒
public static void sleep(long millis,int nanos)throws InterruptedException
设置休眠的毫秒数和纳秒数,一到时间自动唤醒
线程强制执行:join
Thread类中的join()方法原理
- 一般是用在main方法中,用于占用主线程。
- 副线程必须先start再join才有效
- join方法的本质就是用调用方线程给主线程main上锁直到该线程结束才释放
- 遇到join时,主线程立即被占用,不会存在安全问题,因为本质就是同步机制
- 如果同时存在两个以上的副线程,并且同时对main用join上锁,那么main线程的恢复执行以最后一次锁结束为准,不同线程之间不受影响,因为他们占用的都是main线程而没有彼此占用
class J1Thread extends Thread{
@Override
public void run() {
for(int i=1;i<100;i++){
System.out.println(Thread.currentThread().getName()+"\t11111111111");
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class J2Thread extends Thread{
public void run() {
for(int i=1;i<100;i++){
System.out.println(Thread.currentThread().getName()+"\t22222222222");
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
J1Thread j1 = new J1Thread();//创建线程对象
J2Thread j2 = new J2Thread();//创建线程对象
for(int i =1;i<100;i++) {//主线程main真正开始的地方
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"\t主线程开始"+i);
}//执行完for循环体才会轮得到后面j1的开始
j1.start();//先创建j1的线程
j1.join();//用j1给主线程main上锁,知道j1结束才释放
for(int i =1;i<100;i++) {//主线程main继续
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"\t主线程中途"+i);
}//执行完for循环体才会轮得到后面j2的开始
j2.start();
for(int i =1;i<100;i++) {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"\t主线程结束"+i);
if(i==90)//for循环体途中用join上锁
j2.join();//然后j2占用main线程,把剩余部分执行完毕
}
}
}
线程让步:yield()
本质:多线程并发执行是多个线程交替执行,对于某一个线程并不会执行一下就马上释放,而是会持续一个随机的很短的时间。因此通过yield方法可以强制让正在占用资源的线程让出资源,让包括自己在内的所有线程去争夺资源。因此
- yield没有join那么强硬,join是直接上锁,yield只是放弃资源让大家重新争夺
- yield也没有sleep那么稳定,yield有极小概率没有任何让步效果,而sleep则稳定延迟
- 执行次数足够多时yield也能明显看到让步效果
- 同样的yield无论写多少个都一样,而同样的sleep写10个就有10倍的延迟效果
class MyThread1 implements Runnable{
public void run() {
for (int i = 100; i < 200; i++) {
System.out.println("11111111礼让");
yield();
}
}
}
class YouThread1 implements Runnable{
public void run() {
for (int i = 100; i < 200; i++) {
System.out.println("22222222");
}
}
}
public class YiledTest {
public static void main(String[] args) {
MyThread1 M1 = new MyThread1();
YouThread1 Y1 = new YouThread1();
Thread T1 = new Thread(M1);
Thread T2 = new Thread(Y1);
T1.start();
T2.start();
}
}
这一礼让基本把自己让没了