• 多线程入门总结


    要更好的理解多线程的话,必须要把多线程的生命周期搞懂。

    多线程的生命周期

    1.新建(New):线程创建以后就处于新建状态,Thread t = new Thread();

    2.就绪(Runnable):当线程调用start()方法就进入就绪状态,线程进入就绪状态后不会立即执行,而是会等待CPU来调用。

    3.运行(Running):当CPU调用就绪的线程就进入运行状态了。

    4.阻塞(Blocked):处于运行状态的线程由于某种原因,暂时放弃对CPU的使用权,此时进入阻塞状态,直到其进入就绪状态线程才能重新调用进入到运行状态。

    根据阻塞原因的不同,阻塞状态可分为三种:

    1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态。

    2.同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

    3.其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    5.死亡(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    线程的创建的常用两种方式

    1.继承Thread类,重写该类的run()方法。

    public class MyThread extends Thread {
    
        private String name;
        private static int num = 10000;
    
        public MyThread(String name) {
            this.name = name;
        }
    
        public void run() {
            for (int i = 1; i > 0; i++) {
                if(num>0){
                    num = num-1;
                }else{
                    break;
                }
                System.out.println("程序" + name + "在运行,当前num值"+num);
            }
        }
    
    
        public static void main(String[] args) {
            Thread thread1 = new MyThread("MyThread1");//新建线程MyThread,线程进入新建状态
            Thread thread2 = new MyThread("MyThread2");
            thread1.start();//线程调用start()进入就绪状态等待CPU调用
            thread2.start();
        }
    }

     2.实现Runnable接口

    public class MyRunnable implements Runnable {
        private String name;
        private static int num = 10000;
    
        public MyRunnable(String name) {
            this.name = name;
        }
    
    
        @Override
        public void run() {
            for (int i = 1; i > 0; i++) {
                if (num > 0) {
                    num = num - 1;
                    System.out.println("程序" + name + "在运行,当前num值" + num);
                } else {
                    break;
                }
            }
        }
    
        public static void main(String[] args) {
            Runnable runnable1 = new MyRunnable("MyRunnable1");
            Runnable runnable2 = new MyRunnable("MyRunnable2");
            Thread thread1 = new Thread(runnable1); //新建线程MyRunnable1,线程进入新建状态
            Thread thread2 = new Thread(runnable2);
            thread1.start(); //调用start方法,进入就绪状态
            thread2.start();
        }
    }

    3.Thread和Runnable的区别

    这里用最经典的买票举例

    先贴代码吧

    public class MyThread extends Thread {
    
        private int num = 5;
        private String name;
    
        public MyThread(String name) {
            this.name = name;
        }
    
        public void run() {
            try {
                for (int i = 1; i > 0; i++) {
                    if (num > 0) {
                        num--;
                    } else {
                        break;
                    }
                    sleep(100);
                    System.out.println(name + "窗口,当前票数" + num);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        public static void main(String[] args) {
            MyThread t1 = new MyThread("A");
            MyThread t2 = new MyThread("B");
            t1.start();
            t2.start();
        }
    }

     用继承Thread方式运行结果可以看到车票被重复卖出了。再来看看实现Runnable接口的方式

    public class MyRunnable implements Runnable {
        
        private int num = 5;
    
        @Override
        public void run() {
            for (int i = 1; i > 0; i++) {
                if (num > 0) {
                    num--;
                    System.out.println(Thread.currentThread().getName() + "窗口,当前票数" + num);
                } else {
                    break;
                }
            }
        }
    
        public static void main(String[] args) {
            Runnable runnable = new MyRunnable();
            new Thread(runnable, "A").start();
            new Thread(runnable, "B").start();
        }
    }

     相信你已经可以看出区别了,但是多运行几次你会发现

     

     这是因为线程执行会出现抢占资源的情况导致不能同步,所以要加上synchronized关键字。

    总结

    实现Runnable接口比继承Thread类所具有的优势:

    (1):适合多个相同的程序代码的线程去处理同一个资源。

    (2):可以避免java中的单继承的限制。

    (3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

    (4):你只要记住实际开发中一般都用实现Runnable的方式就完事了。

  • 相关阅读:
    证券创新之翼 阿里金融云
    通过改变计算机策略来解决“只能通过Chrome网上应用商店安装该程序”的方法及模版文件下载
    VMware Workstation pro 12下载以及序列号
    Centos7下配置Tomcat7以指定(非root)身份运行
    apache2: Could not reliably determine the server's fully qualified domain name
    apache使用ssl数字证书
    苹果远程控制
    excel 组及分级显示制作教程
    Apache 性能优化
    Pigs and chickens
  • 原文地址:https://www.cnblogs.com/caolyl/p/10184050.html
Copyright © 2020-2023  润新知