美文网首页
【多线程入门系列三】线程中的其它方法

【多线程入门系列三】线程中的其它方法

作者: 5d44bc28b93d | 来源:发表于2018-03-12 23:20 被阅读18次
美图.jpg

前章回顾

  • 多线程入门系列二中我们主要说明了以下知识点

    • 线程的挂起与恢复

    • suspend()与resume()的特点:

      • 独占
      • 不同步

多线程其他方法介绍

  • currentThread()

    • 作用:返回代码段正在被哪个线程调用

    • 示例:

      public static void main(String args[]){
          System.out.println(Thread.currentThread().getName());
      }
      
    • 当前方法正在被主线程调用所以输出main

  • getId()方法

    • 作用:获取线程的唯一id

    • 示例:

      public static void main(String args[]){
          System.out.println(Thread.currentThread().getName());
          System.out.println(Thread.currentThread().getId());
      }
      
  • sleep()方法

    • 作用: sleep()方法用于在指定的毫秒内让线程休眠,即暂停执行。

    • 示例:

       public static void main(String args[]){
      try {
          System.out.println("start");
          Thread.sleep(1000);
          System.out.println("end");
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      
    • 总结:次方法在打印start后暂停1秒之后输出end。

    • tips:若在同步代码中,执行此方法并不会释放资源。

  • isAlive()方法

    • 作用:判断线程是否处于活跃状态。活动状态是指线程已启动且尚未终止。线程处于正在运行或者准备开始运行的状态我们就认为线程是活跃状态。
  • yield方法

    yield()方法的作用是放弃当前的cpu的资源。但是放弃的时间是不确定的。有可能刚放弃,马上又获得了cpu的时间片

  • setPriority() 线程的优先级

    • 线程的优先级较高的则优先获得cpu资源。

    • 优先级划分从1-10,如果小于1或者大于10则会抛出异常

    • 优先级具有继承特性,例如如果线程A的优先级设置为6,如果在A线程中启动B线程,则B线程的优先级也为6

    public class ThreadDemo{
        class MyThread extends Thread{
            @Override
            public void run() {
                super.run();
                System.out.println("mythread  priority " + this.getPriority());
                MyThread2 myThread2 = new MyThread2();
                myThread2.start();
            }
        }
        class MyThread2 extends Thread{
            @Override
            public void run() {
                super.run();
                System.out.println("mythread2  priority " + this.getPriority());
            }
        }
        public static void main(String args[]){
            MyThread  myThread =new ThreadDemo().new MyThread();
            myThread.setPriority(6);
            myThread.start();
        }
    }
    
    • 优先级具有随机性。
  • 守护线程 setDaemon()

    • Java多线程中有两种线程,一种是用户线程、另一种是守护线程,通过setDaemon(true)设置。

    • 守护线程是一种特殊的线程,当进程中不存在非守护线程的时候,守护线程会自动销毁

     class MyThread2 extends Thread{
        @Override
        public void run() {
            super.run();
            int i = 0;
            while(true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                i++;
                System.out.println("mythread2 i =  " + i);
            }
        }
    }
    public static void main(String args[]){
        MyThread2  myThread2 =new ThreadDemo().new MyThread2();
        myThread2.setDaemon(true);
        myThread2.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程结束");
    }
    
  • interrupted 与 isInterrupted

    • interrupted 检测当前线程是否中断 具有清除状态的功能。

    • isInterrupted 检测线程是否中断

    • 举例说明:

 ```java
 public class MyThread extends Thread {
            @Override
            public void run() {
                super.run();
                while(true){
                }
            }
            }
class Run {
    public static void main(String[] args) {
         MyThread thread = new MyThread();
        thread.start();
        thread.interrupt();
        System.out.println(thread.interrupted());
        System.out.println(thread.isInterrupted());
        Thread.currentThread().interrupt();
        System.out.println(
        Thread.currentThread().isInterrupted()
                    );
        System.out.println(
        Thread.currentThread().interrupted()
                    );
        System.out.println(
        Thread.currentThread().interrupted()
                    );
            
            }
        
```
  • 前面两个输出分别为false,true,因为interrupted检测当前线程是否中断,而当前线程为main方法的主线程并且并未中断所以为false,而isInterrupted则检测线程是否中断,可以看出线程调用了interrupt方法确实是使其中断标志位为true,细心的可以发现如果在while循环里面加上打印输出,interrupt方法并没有真正的中断线程,仅仅的修改了标志位。

    • 后面三个输出分别为true true false ,最后一个输出为false是因为interrupted调用后重置了标志位。
  • suspend()与resume()的用法

    • 代码实例

      public class MyThread extends Thread {
          @Override
          public void run() {
              super.run();
              for (int i = 0; i < 500000; i++) {
                  System.out.println(this.getName()+" 运行中" + i);
              }
          }
      }
      
      class Run {
          public static void main(String[] args) {
              try {
                  MyThread thread = new MyThread();
                  thread.setName("A");
                  thread.start();
                  Thread.sleep(100);
                  thread.suspend();
                  thread.setName("B");
                  Thread.sleep(3000);
                  thread.resume();
                  thread.interrupt();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
    • 分析:

      • 从打印结果来看线程确实是先被挂起,让你后重新恢复运行。说明suspend与resume方法确实起到了作用。
  • suspend()与resume()的缺陷--独占
    在使用suspend()与resume()方法时极易造成公共资源被独占从而使得其他线程无法访问公共资源。其次如果没有调用suspend()方法直接调用resume()方法是不起作用的。因此这两个方法也不建议使用,被标注为过时方法。

    • 代码实例

      public class MyThread extends Thread {
          @Override
          public void run() {
              super.run();
              int i=0;
              while (true) {
                  i++;
      
              }
          }
      }
      
      class Run {
          public static void main(String[] args) {
              try {
                  MyThread thread = new MyThread();
                  thread.setName("A");
                  thread.start();
                  Thread.sleep(100);
                  thread.suspend();
                  System.out.println("运行结束");
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
      
    • 上面例子会打印出运行结束。此时不能证明保持了独占,如果将例子稍微改成下面的方式:

      public class MyThread extends Thread {
      @Override
          public void run() {
              super.run();
              int i = 0;
              while (true) {
                  i++;
                  System.out.println(this.getName() + " 运行中" + i);
              }
          }
      }
      
      class Run {
          public static void main(String[] args) {
              try {
                  MyThread thread = new MyThread();
                  thread.setName("A");
                  thread.start();
                  Thread.sleep(100);
                  thread.suspend();
                  System.out.println("运行结束");
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
      
    • 此时并不会打印出"运行结束"字符。原因如下:println()方法是同步的,当线程进入println()方法时获得了同步锁,而此时挂起线程导致同步锁不被释放,所以主线程的println()方法不会执行。这就是独占特性。

  • suspend() 与 resume() 的缺陷----不同步

    class User{
        private String name="123";
        private String pwd="****";
        public void setValues(String name, String pwd){
            this.name = name;
            if(Thread.currentThread().getName().equals("a")){
                Thread.currentThread().suspend();
            }
            this.pwd = pwd;
        }
        public void printValues(){
            System.out.println("name= " + this.name);
            System.out.println("pwd= " + this.pwd);
        }
    }
    public class MyThread extends Thread {
        private User user;
        public MyThread(User user){
            this.user = user;
            this.setName("a");
        }
        @Override
        public void run() {
            super.run();
        user.setValues("abc","456");
        }
    }
    
    class Run {
        public static void main(String[] args) {
            try {
                User user = new User();
                MyThread thread = new MyThread(user);
                thread.start();
                Thread.sleep(1000);
                user.printValues();
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 通过上面的结果可以看出只有用户名被修改了,而用户密码并未修改,造成了数据的不同步。

相关文章

网友评论

      本文标题:【多线程入门系列三】线程中的其它方法

      本文链接:https://www.haomeiwen.com/subject/xpnqfftx.html