第七天学习多线程的各种方法
多线程的各种方法
线程状态
- 新生状态:创建(new)一个线程。
- 就绪状态:调用start()时,线程就等待cpu调度。
- 运行状态:cpu开始调度,进入运行状态,线程执行线程体代码块。
- 阻塞状态:当调用sleep、wait、同步锁时,线程进入阻塞状态,代码不会继续执行,等待阻塞结束后,重新进入就绪状态,等待cpu调度。
- 死亡状态:线程中断或结束即进入死亡状态,线程再不能。
线程方法
setPriority(int newPriority) //更改线程优先级
static void sleep(long millis) //指定毫秒内让当前线程休眠
void join() //等待线程终止
static void yield() //暂停当前线程,执行其它线程
void interrupt() //中断线程
boolean isAlive() //测试线程是否处于活动状态
停止线程
-
建议线程正常停止(利用次数,不建议死循环)
-
建议使用标志位
-
不要使用stop或destroy等过时或JDK不建议使用的方法。
package thread;
public class ThreadTest implements Runnable {
//1.设置一个标志位
private boolean flag = true;
//线程体
@Override
public void run() {
int i = 0;
while (flag){//当flag==false时线程停止
System.out.println("线程在运行"+i++);
}
}
//2.设置一个公开方法,转换标志位
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
new Thread(threadTest).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if (i==900){
threadTest.stop();
System.out.println("线程停止了");
}
}
}
}
休眠线程_sleep
- sleep指定当前线程阻塞毫秒数。
- sleep存在异常interruptedException。
- sleep时间到达后,线程进入就绪状态。
- sleep可以模拟网络延时,倒计时
- 每一个对象都有一个锁,sleep不会释放锁。
线程休眠作用
- 模拟网络延时,放大问题发生性(代码见多线程创建博客)。
- 模拟倒计时
package thread;
//倒计时
public class TestSleep {
public static void tenDown() throws InterruptedException {
int num=10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num<=0){
break;
}
}
}
public static void main(String[] args) throws InterruptedException {
tenDown();
}
}
线程礼让_yield
- 礼让线程,让当前正在执行的线程暂停,但不阻塞。
- 将线程从运行状态转换为就绪状态。
- 让cpu重新调度,礼让不一定成功,看cpu心情(线程A在运行,B在就绪,A执行了yield方法,A、B同时就绪,但第二次cpu又调度了A)。
线程强制执行_join
- join合并线程,此线程执行后,其它线程才执行。
package thread;
//测试join
public class TestJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("VIP来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
//主线程
for (int i = 0; i < 1000; i++) {
if (i==50){
thread.join();
}
System.out.println("main"+i);
}
}
}
- 一开始run线程和main主线程一起跑,当主线程 i==50 时,开始全部跑run线程。
观察线程状态
package thread;
//观察测试线程状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("////////");
});
//观察创建后
Thread.State state = thread.getState();
System.out.println("观察线程启动时的状态---------------》"+state);
//观察启动后
thread.start();
state = thread.getState();
System.out.println("观察线程运行时的状态---------------》"+state);//run
//TERMINATED线程终止
while (state!=Thread.State.TERMINATED){
Thread.sleep(100);
state = thread.getState();//更新线程状态
System.out.println("观察线程休眠时(阻塞)和结束的状态---------------》"+state);
}
thread.start();//这里会爆出异常,线程死亡后就在其不能了!
}
}
- 使用thread.getState()方法即可观察到线程状态。
线程的优先级
- 线程优先级越高,越容易被cpu调度。默认为5,可设置1-10。
package thread;
//测试线程优先级
public class TestPriorty extends Thread{
public static void main(String[] args) {
//主线程默认优先级
System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
MyPriority testPriorty = new MyPriority();
Thread thread1 = new Thread(testPriorty,"1");
Thread thread2 = new Thread(testPriorty,"2");
Thread thread3 = new Thread(testPriorty,"3");
Thread thread4 = new Thread(testPriorty,"4");
//默认优先级为5
thread1.start();
thread2.setPriority(1);
thread2.start();
thread3.setPriority(4);
thread3.start();
thread4.setPriority(10);
thread4.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
}
}
守护线程_daemon
- 线程分为用户线程和守护线程。
- 虚拟机必须确保用户线程执行完毕(main())。
- 虚拟机不用等待守护线程执行完毕(gc())。
package thread;
//测试守护线程
//上帝守护你
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false表示用户线程,正常的线程都是用户线程
//上帝 守护线程启动
thread.start();
//你 用户线程启动
new Thread(you).start();
}
}
//上帝
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝保佑你一生");
}
}
}
//你
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 365000; i++) {
System.out.println("开心的活了一生");
}
System.out.println("=============================Goodbye world");
}
}
- 当用户线程执行结束后,守护线程还在执行。