控制线程

线程状态转换

线程控制基本方法

方法

功能

isAlive()

判断线程是否终止

getpriority()

获得线程的优先级数值

setpriority()

设置线程优先级数值

Thread.sleep()

设置当前线程睡眠指定毫秒数

join()

调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行

yield()

让出CPU,让当前线程进入就绪队列等待调度

wait()

当期线程进入对象的wait pool

notify()/notifyAll()

唤醒对象的wait pool中的一个/所有等待线程

sleep/join/yield方法

  • sleep方法(暂停执行线程)
import java.io.*;
import java.util.*;
public class TestThread1 {
    public static void main(String[] args) {
        MyThread m = new MyThread();
        Thread t = new Thread(m);
        t.start();
        try{
            Thread.sleep(10000);//10秒钟
            //在哪个线程中调用的sleep方法,就让哪个线程睡眠
        }catch(InterruptedException e){}
        t.interrupt();//打断睡眠线程
    }
}
class MyThread implements Runnable{
    public void run(){
        while(true){
            System.out.println("-----" + new Date() + "-----");
            try{
                Thread.sleep(1000);//1秒钟
            }catch (InterruptedException e){
                return;
            }
        }
    }
}

 改程序执行过程是:每隔一秒钟打印一次时间,打印10次(10秒钟过后),主线程被唤醒,执行interrupt方法,打断MyThread线程,因为Mythread线程被打断,sleep方法就会捕捉到异常,执行return,终止程序

 这种终止线程的方式并不推荐,Thread类中的stop方法也是停止线程,但是也不推荐,推荐的方法写法

import java.util.*;
public class TestThread1 {
    public static void main(String[] args) {
        MyThread m = new MyThread();
        Thread t = new Thread(m);
        t.start();
        try{
            Thread.sleep(10000);
            m.flag = false;
        }catch(InterruptedException e){}
        
    }
}
class MyThread implements Runnable{
    boolean flag = true;
    public void run(){
        while(flag){
            System.out.println("-----" + new Date() + "-----");
            try{
                Thread.sleep(1000);//1秒钟
            }catch (InterruptedException e){
                return;
            }
        }
    }
}
  • join方法(合并线程)
public class TestJoin {
    public static void main(String[] args) {
        MyThread t1 = new MyThread("t1");
        t1.start();
        try {
            t1.join();
        }catch(InterruptedException e) {}
        for(int i = 1;i <= 10;i++)
            System.out.println("i am main Thread");
    }
}
class MyThread extends Thread{
    MyThread(String s){
        super(s);
    }
    public void run() {
        for(int i = 1;i <= 10;i++)
            System.out.println("i am " + getName());
        try {
            sleep(1000);
        }catch(InterruptedException e){
            return;
        }
    }
}

 程序运行结果如下:

 join会将线程添加到当前执行的线程中来执行,对于上述程序,会将MyThread线程添加到主线程中执行,MyThread线程执行完了,才会继续执行主线程  用一个图来解释上述程序的执行过程:

  • yield方法(让出CPU,给其他线程执行的机会)
public class TestYield {
    public static void main(String[] args) {
        MyThread2 t1 = new MyThread2("t1");
        MyThread2 t2 = new MyThread2("t2");
        t1.start();
        t2.start();
    }
}
class MyThread2 extends Thread{
    MyThread2(String s){
        super(s);
    }
    public void run() {
        for(int i = 1;i <= 15;i++) {
            System.out.println(getName() + ":" + i);
            if(i % 5 == 0)
                yield();
        }
    }
}

 程序执行过程见下图:

 观察这个程序结果我们能发现,不论当前执行的线程是t1还是t2,每当到了5的倍数,下一次执行的一定是另一个线程,这就是yield方法的作用,让出当前CPU给其他线程

线程的优先级

  • 线程的优先级用数字表示,范围从1到10,一个线程的默认优先级是5
    • Thread.MIN_PRIORITY = 1
    • Thread.MAX_PRIORITY = 10
    • Thread.NORM_PRIORITY = 5
  • 使用下述方法可以获得或设置线程对象的优先级
    • int getPriority()
    • void setPriority(int newPriority)
public class TestPriority {
    public static void main(String[] args) {
        Thread t1 = new Thread(new T1());
        Thread t2 = new Thread(new T2());
        t1.setPriority(Thread.NORM_PRIORITY + 4);
        t1.start();
        t2.start();
    }
}
class T1 implements Runnable{
    public void run() {
        for(int i = 0;i < 100;i++)
            System.out.println("T1:" + i);
    }
}
class T2 implements Runnable{
    public void run() {
        for(int i = 0;i < 100;i++)
            System.out.println("-----T2:" + i);
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

10:判决素数个数

10:判决素数个数 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB描述 输入两个整数X和Y,输出两者之间的素数个数(包括X和Y...

39360
来自专栏上善若水

如何识别C++编译以后的函数名

C/C++语言在编译以后,函数的名字会被编译器修改,改成编译器内部的名字,这个名字会在链接的时候用到。如果用backtrace之类的函数打印堆栈时,显示的就是被...

29520
来自专栏尾尾部落

[剑指offer] 用两个栈实现队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

9910
来自专栏林德熙的博客

C# 动态加载卸载 DLL

我最近做的软件,需要检测dll或exe是否混淆,需要反射获得类名,这时发现,C#可以加载DLL,但不能卸载DLL。于是在网上找到一个方法,可以动态加载DLL,不...

20410
来自专栏菩提树下的杨过

java学习:JMM(java memory model)、volatile、synchronized、AtomicXXX理解

一、JMM(java memory model)内存模型 从网上淘来二张图: ? 上面这张图说的是,在多核CPU的系统中,每个核CPU自带高速缓存,然后计算机主...

214100
来自专栏我是业余自学C/C++的

汇编语言-第三章 寄存器(栈存储)

35610
来自专栏大内老A

采用一个自创的"验证框架"实现对数据实体的验证[设计篇]

没有想到自己头脑发热写了一个简陋版本的所谓“验证框架”能够得到众多网友的推荐。个人觉得这个验证框架有两个主要的特点是:提供CompositeValidator使...

20980
来自专栏王磊的博客

Java并发编程(一)Thread详解

由上描述,可以得知线程作为cpu的基本调度单位,只有把多线程用好,才能充分利用cpu的多核资源。

7010
来自专栏Golang语言社区

Go Channel 源码剖析

0. 引言 这篇文章介绍一下 Golang channel 的内部实现,包括 channel 的数据结构以及相关操作的代码实现。代码版本 go1.9rc1,部分...

72760
来自专栏拂晓风起

中文URL编码

19850

扫码关注云+社区

领取腾讯云代金券