多线程笔记:多线程基础 - 1

1.线程的创建和启动方式:
    1.自定义类,让其继承Thread并重写run()方法,创建此类的对象。调用start()方法启动
        public class MyThread extends Thread {    //自定义线程类
            @Override
            public void run() {
                。。。
            }
        }
        
        MyThread t1 = new MyThread();        //创建
        t1.start();        //启动
    2.自定义类实现runnable接口,实现run()方法,创建Thread对象并传入这个实现类。调用start()方法启动
        public class MyThread2 implements Runnable {    //实现类
            @Override
            public void run() {
                。。。
            }
        }
        
        MyRunnable r = new MyRunnable();    
        Thread t1 = new Thread(r);    //创建线程
        t1.start();        //    启动  
        
        注意:只有Thread对象才有start()方法用于启动线程
        
        
2.线程之间数据共享
    1.创建runnable实现类或继承Thread,重写run()方法:
        public class MyRunnable implements Runnable {
            private int count = 100;        //要共享的变量
            @Override
            public void run() {
                while (count > 0) {
                    try {
                        Thread.sleep(100);
                        count --;
                        System.out.println(count);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        
    2.创建多个线程,
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
        
        此时t1,t2共享了变量count
    
    注意:这里有线程安全问题
    
3.Thread的方法:
    Thread.currentThread()        //静态方法,获取当前正在运行线程(执行此代码的线程)对象
    isAlive()     //检查线程是否处于活动状态,活动状态:线程已经启动且尚未停止
    Thread.sleep()        //静态方法,让当前线程(执行此代码的线程)休眠
    getId()      //获取线程的唯一标识
    
    
    例子:
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r);
        System.out.println(Thread.currentThread().getName());    
        System.out.println(Thread.currentThread().getId());
        System.out.println(t1.getName());
        System.out.println(t1.getId());
        Thread.sleep(1000);
        System.out.println(t1.isAlive());
        t1.start();
        System.out.println(t1.isAlive());
        
        运行结果:
            main
            1
            Thread-0
            11
            false
            true
    
4.线程的停止
    1. interrupt(); 用于停止线程的方法    //做了一件事:将线程停止状态的值置为了true
    
        注意!!这里调用interrupt()方法停止线程,所谓停止线程并不是说线程执行完这个方法后就不执行了。调用此方法
        仅仅是改变了线程的状态。线程中有一个标识线程是否停止的状态值。interrupt()方法将此值置为true,线程将继续往下执行。
        
        例子:
            System.out.println("执行前");
            Thread.currentThread().interrupt();
            System.out.println("执行后");    
            
            运行结果:
                执行前
                执行后        //调用interrupt方法后,线程依然在执行
        
        
    2.查看停止状态的方法:
        1. isInterrupted()    //用于查看线程状态,返回boolean
            
            例子:
                System.out.println("执行前");
                boolean status1 = Thread.currentThread().isInterrupted();
                System.out.println(status1);

                Thread.currentThread().interrupt();

                boolean status2 = Thread.currentThread().isInterrupted();
                System.out.println(status2);
                System.out.println("执行后");
    
                运行结果:
                    执行前
                    false        //执行前为false
                    true        //执行后为true
                    执行后
                    
        2.interrupted()        //也是用于查看线程状态,为静态方法
            例子:
                System.out.println("执行前");
                System.out.println(Thread.interrupted());
                
                Thread.currentThread().interrupt();
                
                System.out.println(Thread.interrupted());    //返回线程状态,并重置状态为false
                System.out.println(Thread.interrupted());    //再次调用返回false,因为interrupted()返回线程状态的同时,会重置线程的状态为false
                System.out.println("执行后");
    
                运行结果:
                    执行前
                    false
                    true
                    false
                    执行后
                    
        注意:线程的状态初始值为false, 调用start()方法启动线程前是false, 执行完后,如果是true会被重置为false
            因此,此状态值是在线程执行过程中才有意义。
            
    3.两个方法的区别:
        1.isInterrupted()为非静态方法,interrupted()为静态方法。isInterrupted()查看的是调用此方法的线程的状态
            interrupted()查看的是执行当前行代码的线程的状态
        2.isInterrupted()不会重置状态为false,interrupted()调用完会重置状态为false
        
        
    
    
    4.sleep()方法与线程停止    
        当线程停止状态为true时,调用sleep会抛异常
        调用sleep()进行线程休眠,在休眠过程中,如果线程停止状态由false变为true时,也会抛异常
    
        例子:
            Thread.sleep(1000);
            System.out.println("执行前,状态:" + Thread.currentThread().isInterrupted());
            Thread.currentThread().interrupt();
            System.out.println("执行后,状态:" + Thread.currentThread().isInterrupted());
            Thread.sleep(1000);
    
            运行结果:
                执行前,状态:false
                执行后,状态:true
                java.lang.InterruptedException: sleep interrupted
                    at java.lang.Thread.sleep(Native Method)
                    at com.huawei.controller.ThreadController.main(ThreadController.java:31)
    
            
            public class MyRunnable implements Runnable {
                private int count = 100;
                @Override
                public void run() {
                    try {
                        System.out.println("线程执行");
                        Thread.sleep(1000);        //休眠
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            
            MyRunnable r = new MyRunnable();
            Thread t1 = new Thread(r);
            t1.start();
            t1.interrupt();    //线程休眠时,改变状态为true
    
            运行结果:
                线程执行
                java.lang.InterruptedException: sleep interrupted
                    at java.lang.Thread.sleep(Native Method)
                    at com.huawei.thread.MyRunnable.run(MyRunnable.java:18)
                    at java.lang.Thread.run(Thread.java:745)
    
5.让线程真正停止的方法,即不是改变停止状态,而是停止执行的方法:stop()  //暴力终止线程执行,为已过时的方法    
    例子:
        public class MyRunnable implements Runnable {
            private int count = 100;
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("线程执行,循环次数:" + (i + 1));
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r);
        t1.start();
        Thread.sleep(3000);
        t1.stop();
    
        运行结果:
            线程执行,循环次数:1
            线程执行,循环次数:2
            线程执行,循环次数:3        //循环三次后,线程被终止,不再执行  //真正的停止

            Process finished with exit code 0
    
    调用slop()方法终止线程可能造成的问题:
        1.可能使一些清理性的工作得不到完成
        2.终止线程时会释放锁,这种释放是非正常释放,可能造成数据不一致问题。
        
6.不适用stop()完成线程终止:
    采用停止状态进行控制,实现线程终止:如果停止状态为true,则抛出异常,或者使用return停止线程
    
    例子:
    
        public class MyRunnable implements Runnable {
            private int count = 100;
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("线程执行,循环次数:" + (i + 1));
                        Thread.sleep(1000);
                        if (Thread.interrupted()) {        //检查状态
                            throw new InterruptedException();    //如果问停止状态,则抛异常终止代码运行
                            //return;        //或者使用return终止,此时也会抛出InterruptedException异常
                        }
                    }
                } catch (InterruptedException e) {
                    System.out.println("线程终止,进行垃圾清理等工作。。。");        //线程执行停止后进行后续清理等工作
                }
            }
        }
    
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r);
        t1.start();
        Thread.sleep(3000);
        t1.interrupt();        //调用interrupt方法改变停止状态而不是暴力终止

 

posted @ 2019-07-07 18:15  foreast  阅读(168)  评论(0编辑  收藏  举报