• Java之线程


    目录

    创建线程

    继承Thread类来创建线程 

    实例 

     创建Thread类对象来创建线程

    实例

     实现Runnable接口来创建线程 

    实例

    Thread类的常用方法

    Thread类的构造方法 

    public Thread()

    public Thread(String name)

    public Thread(Runnable target)

    public Thread(Runnable target,String name)

    Thread类常用的方法  

    getName()获取某个进程的进程名称

    setName()修改某个进程的进程名称

    Thread.currentThread()获取当前线程的对象

    isAlive()确认某个线程是否存活

    getPriority()获取某个线程的优先权

    setPriority()设定某个线程的优先权

    sleep()线程的延时函数

    实例

    线程同步

    同步的机制

    实例(没有使用synchronized关键字锁住共享资源时)

    实例(使用synchronized关键字锁住共享资源时) 

    线程的等待和唤醒

    wait()

    notify()

    notifyAll()

    实例

     


     

    创建线程

    继承Thread类来创建线程 

    class Athread extends Thread {
            public void run(){} 
    }

    public class Text {
            public static void main(String[] args) {
                    new Athread().start();  //启动线程
            }    
    }

     

    实例 

    1. //继承THread类来创建线程
    2. class Athread extends Thread {
    3. public void run(){ //重写Thread类的run()方法,该方法在调用Thread类的start()方法时自动执行
    4. while(true){
    5. System.out.println("我是线程A");
    6. try {
    7. Thread.sleep(1000); //使用Thread类的静态方法,延时函数将线程A挂起1s
    8. } catch (InterruptedException e) {
    9. e.printStackTrace();
    10. }
    11. }
    12. }
    13. }
    14. class Bthread extends Thread {
    15. public void run(){
    16. while(true){
    17. System.out.println("我是线程B");
    18. try {
    19. Thread.sleep(1000);
    20. } catch (InterruptedException e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. }
    25. }
    26. public class Text {
    27. public static void main(String[] args) {
    28. new Athread().start(); //启动线程A
    29. new Bthread().start(); //启动线程B
    30. }
    31. }

     创建Thread类对象来创建线程

    public class Text {
            public static void main(String[] args) {

                    Thread Athread = new Thread() {
                             public void run() {}  
                    };

            Athread.start();  //启动线程A 
            }
    }

    实例

    1. public class Text {
    2. public static void main(String[] args) {
    3. //创建Thread类对象
    4. Thread Athread = new Thread() {
    5. public void run() { //重写Thread类的run()方法,该方法在调用Thread类的start()方法时自动执行
    6. while(true){
    7. System.out.println("我是线程A");
    8. try {
    9. Thread.sleep(1000); //使用Thread类的静态方法,延时函数将线程A挂起1s
    10. } catch (InterruptedException e) {
    11. e.printStackTrace();
    12. }
    13. }
    14. }
    15. };
    16. Thread Bthread = new Thread() {
    17. public void run() {
    18. while(true){
    19. System.out.println("我是线程B");
    20. try {
    21. Thread.sleep(1000);
    22. } catch (InterruptedException e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. }
    27. };
    28. Athread.start(); //启动线程A
    29. Bthread.start(); //启动线程B
    30. }
    31. }

     实现Runnable接口来创建线程 

    class AThread implements Runnable {  //实现Runnable接口
            public void run() {}   
    }


    public class Text {
            public static void main(String[] args) {
                    Thread a = new Thread(new AThread());
                     a.start();  //启动线程
            }
    }

    实例

    1. class AThread implements Runnable {
    2. public void run() {
    3. while(true){
    4. System.out.println("我是线程A");
    5. try {
    6. Thread.sleep(1000); //使用Thread类的静态方法,延时函数将线程A挂起1s
    7. } catch (InterruptedException e) {
    8. e.printStackTrace();
    9. }
    10. }
    11. }
    12. }
    13. class BThread implements Runnable {
    14. public void run() {
    15. while(true){
    16. System.out.println("我是线程B");
    17. try {
    18. Thread.sleep(1000); //使用Thread类的静态方法,延时函数将线程A挂起1s
    19. } catch (InterruptedException e) {
    20. e.printStackTrace();
    21. }
    22. }
    23. }
    24. }
    25. public class Text {
    26. public static void main(String[] args) {
    27. Thread a = new Thread(new AThread());
    28. a.start();
    29. Thread b = new Thread(new BThread());
    30. b.start();
    31. }
    32. }

    Thread类的常用方法

    Thread类的构造方法 

    public Thread()

    创建一个Thread对象

    public Thread(String name)

    创建一个Thread对象,参数name是设定线程对象的名称。

    Thread t1 = new Thread("线程1")  //设定线程对象名称为线程1

    public Thread(Runnable target)

    创建一个Thread对象,参数target是Runnable接口类型的对象,此构造方法将实现Runnable接口的类的对象放在Thread对象中,启动线程时会执行target对象的run()方法。

    class AThread implements Runnable {  //实现Runnable接口
            public void run() {}   
    }


    public class Text {
            public static void main(String[] args) {
                    Thread a = new Thread(new AThread());
                    a.start();  //启动线程
            }
    }

    public Thread(Runnable target,String name)

    创建一个Thread对象,参数name是设定线程对象的名称,参数target是Runnable接口类型的对象。

    Thread类常用的方法  

    getName()获取某个进程的进程名称

    Thread a = new Thread();

    a.getName();  //获取某个进程的线程名称

    setName()修改某个进程的进程名称

    Thread a = new Thread(String);

    a.setName();  //修改某个进程的线程名称

    Thread.currentThread()获取当前线程的对象

    Thread a = new Thread(); 
    Thread.currentThread();  //获取当前线程的对象

    isAlive()确认某个线程是否存活

    Thread a = new Thread(); 
    a.isAlive(); //确认线程是否存活,如果存活返回true,如果死亡返回false 

    getPriority()获取某个线程的优先权

    Thread a = new Thread(); 
    a.getPriority();  //获取某个线程的优先权,默认为5 

    setPriority()设定某个线程的优先权

    Thread类的优先权常量:

    • Thread.MIN_PRIORITY:数值为1,最低优先权
    • Thread.NORM_PRIORITY :数值为5,默认优先权
    • Thread.MAX_PRIORITY:数值为10,最高优先权

    Thread a = new Thread(); 

    a/​​​​​​.setPriority(int);  //设定某个线程的优先权,默认为5,最低为1,最高为10,处于就绪队列中的线程优先权越高,越先被执行

    sleep()线程的延时函数

    Thread a = new Thread(); 
    Thread.sleep(int);  //让线程挂起(延时)一段毫秒时间

    实例

    1. public class Text {
    2. static int cnt = 0;
    3. static public void inspectThread(Thread obj){
    4. if(obj.isAlive() == true){ //isAlive()确认线程是否存活,如果存活返回true,如果死亡返回false
    5. System.out.println("线程还活着");
    6. }else if(obj.isAlive() == false){
    7. System.out.println("线程已经死了");
    8. }else{
    9. System.out.println("不知道线程的状态");
    10. }
    11. }
    12. public static void main(String[] args) {
    13. Thread a = new Thread("线程1"){
    14. public void run() {
    15. while(true){
    16. System.out.println("jiangxiaoya");
    17. cnt += 1;
    18. if(cnt == 5){
    19. break;
    20. }
    21. try {
    22. Thread.sleep(3000); //sleep()线程的延时函数:将线程A挂起3s
    23. } catch (InterruptedException e) {
    24. e.printStackTrace();
    25. }
    26. }
    27. }
    28. };
    29. System.out.println(a.getName()); //getName()获取某个进程的线程名称
    30. a.setName("myThread"); //setName()修改某个进程的线程名称
    31. System.out.println(a.getName());
    32. Thread.currentThread().setName("线程1"); //Thread.currentThread()获取当前线程的对象
    33. a.start();
    34. inspectThread(a);
    35. System.out.println(a.getPriority()); //getPriority()获取某个线程的优先权,默认为5
    36. a.setPriority(9); //setPriority()设定某个线程的优先权,默认为5,最低为1,最高为10,处于就绪队列中的线程优先权越高,越先被执行
    37. try{
    38. a.join(); //等待线程对象a的线程执行完毕
    39. }catch (InterruptedException e) {
    40. e.printStackTrace();
    41. }
    42. inspectThread(a);
    43. }
    44. }

    2abe25b1a8e94b5cb076747813f78f19.png

    线程同步

    线程同步主要是为了避免同一个时间点有多个线程同时访问同一个共享资源(例如对象)而造成的数据错误。

    同步的机制

    Java的关键字synchronizedH会把程序块锁入一个房间中,房间每次只能允许一个线程进入,线程对象进入房间前会去房间门口领取钥匙。例如A线程是第一个访问这个房间的,那么A线程就直接领取房间门口的钥匙进入房间,后面的线程B和线程C也来到房间门口,但线程B和线程C需要阻塞等待(进入中断状态)线程A从房间出来归还钥匙后才能领取钥匙进入房间。

    实例(没有使用synchronized关键字锁住共享资源时)

    1. class myThread implements Runnable {
    2. int grabed; //已经偷得的金条数量
    3. static int totalGold = 200000; //金条总数
    4. Thread t;
    5. public myThread(String name) { //构造方法
    6. t = new Thread(this,name); //this == (t1)new myThread();
    7. t.start(); //启动线程
    8. }
    9. private static boolean grabGold() { //判断金条是否剩余,如果剩余还能偷取
    10. if(totalGold > 0){
    11. totalGold--; //偷取一条金条
    12. return true;
    13. }else {
    14. return false;
    15. }
    16. }
    17. public void run() {
    18. while(grabGold()){
    19. grabed++; //获得一条金条
    20. }
    21. System.out.println(t.getName() + "总共偷得金条" + grabed +"条");
    22. }
    23. }
    24. public class Text {
    25. public static void main(String[] args) {
    26. System.out.println("共有金条" + myThread.totalGold +"条");
    27. myThread t1 = new myThread("A"); //创造线程A去偷金条
    28. myThread t2 = new myThread("B"); //创造线程B去偷金条
    29. myThread t3 = new myThread("C"); //创造线程C去偷金条
    30. }
    31. }

    d3170cdaa1114e20a3e566a23ba1b8f8.png

    实例(使用synchronized关键字锁住共享资源时) 

    1. class myThread implements Runnable {
    2. int grabed; //已经偷得的金条数量
    3. static int totalGold = 200000; //金条总数
    4. Thread t;
    5. public myThread(String name) { //构造方法
    6. t = new Thread(this,name); //this == (t1)new myThread();
    7. t.start(); //启动线程
    8. }
    9. //当使用synchronized关键字将金条(共享资源)放进一个房间时,一次只能由一个线程偷取
    10. private synchronized static boolean grabGold() { //判断金条是否剩余,如果剩余还能偷取
    11. if(totalGold > 0){
    12. totalGold--; //偷取一条金条
    13. return true;
    14. }else {
    15. return false;
    16. }
    17. }
    18. public void run() {
    19. while(grabGold()){
    20. grabed++; //获得一条金条
    21. }
    22. System.out.println(t.getName() + "总共偷得金条" + grabed +"条");
    23. }
    24. }
    25. public class Text {
    26. public static void main(String[] args) {
    27. System.out.println("共有金条" + myThread.totalGold +"条");
    28. myThread t1 = new myThread("A"); //创造线程A去偷金条
    29. myThread t2 = new myThread("B"); //创造线程B去偷金条
    30. myThread t3 = new myThread("C"); //创造线程C去偷金条
    31. }
    32. }

    44325170564745ffbb6bdcf48aabade2.png

    线程的等待和唤醒

    Object对象中提供wait()、notify()、notifyAll()方法可以让线程间相互设定等待或者唤醒。

    wait()

    让指定的线程进入等待队列成为等待状态。wait()方法必须写在synchronized程序块中,并用try...catch捕获异常。另外,为避免其他线程执行notify()方法或notifyAll()方法时唤醒不能唤醒的线程,所谓wait()方法必须写在while等循环中,并配合满足循环的条件。

    notify()

    唤醒一个在等待队列等待的线程,哪个线程被唤醒则由JVM决定。

    notifyAll()

    唤醒所有在等待队列等待的线程,哪个线程会先执行则由JVM决定。

    实例

     

    1. class Baseball {
    2. private boolean isThrow = false; //棒球初始状态为未投出
    3. public synchronized void pBall(int tNo){ //投球机
    4. while(isThrow){ //如果已经投球就等待击打者打球
    5. try{
    6. wait(); //进入等待状态
    7. } catch (InterruptedException e){}
    8. }
    9. //投球
    10. System.out.println("投出第 " + tNo + " 颗棒球");
    11. isThrow = true;
    12. notify(); //唤醒击打者
    13. }
    14. public synchronized void hBall(int aNo){ //击打
    15. while(!isThrow){ //如果已经打球就等待投球机投球
    16. try{
    17. wait(); //进入等待状态
    18. } catch (InterruptedException e){}
    19. }
    20. //打球
    21. System.out.println("第 " + aNo + " 次挥棒");
    22. isThrow = false;
    23. notify(); //唤醒投球机
    24. }
    25. }
    26. class Pitching implements Runnable {
    27. Baseball baseball;
    28. Pitching(Baseball baseball){
    29. this.baseball = baseball;
    30. }
    31. public void run() {
    32. for (int i = 1; i <= 5; i++){ //投5次球
    33. baseball.pBall(i);
    34. }
    35. }
    36. }
    37. class Hit implements Runnable {
    38. Baseball baseball;
    39. Hit(Baseball baseball){
    40. this.baseball = baseball;
    41. }
    42. public void run() {
    43. for (int i = 1; i <= 5; i++){ //打5次球
    44. baseball.hBall(i);
    45. }
    46. }
    47. }
    48. public class Text {
    49. public static void main(String[] args) {
    50. Baseball baseball = new Baseball(); //
    51. Thread A = new Thread(new Pitching(baseball)); //A线程投球
    52. Thread B = new Thread(new Hit(baseball)); //B线程打球
    53. A.start();
    54. B.start();
    55. }
    56. }

    ef0de3c983564c5185bdc5aebe3d06e6.png

     

     

     

  • 相关阅读:
    [stm32]温湿度采集与OLED显示
    信息系统项目管理教程(第4版):第二章 信息技术及其发展
    通过融合UGV的地图信息和IMU的惯性测量数据,实现对车辆精确位置和运动状态的估计和跟踪研究(Matlab代码实现)
    RocketMQ(五)RocketMQ集群架构
    优秀的项目经理如何寻找到价值贡献点?如何成为价值型项目经理?
    卧槽,2行代码,让接口性能提升10倍
    (02)Cartographer源码无死角解析-(21) MapBuilder→AddTrajectoryBuilder()
    【猿创征文|Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏地图绘制(2-1)
    一个动态规划的简单例题
    使用OpenVINO实现飞桨版PGNet推理程序
  • 原文地址:https://blog.csdn.net/weixin_54076783/article/details/127721682