多线程——创建线程和常用线程方法

首先弄清线程是什么。比如我们打开的一个应用,XX.exe,这就是一个进程,进程可以在电脑的任务管理器里面看见。但是在这个进程的内部,需要同时做一些事情,比如QQ的传文件或者微信的聊天,这些单独的任务就是一个线程,如果同时进行就需要多线程来实现。

1.创建多线程——继承线程类

继承Thread类,然后重写run方法,最后调用start方法。

class Thread_extend extends Thread{
  //重写run方法
public void run(){ System.out.println("This is Thread"); } } class Thread_start{ public static void main(String[] args){
     //创建一个Thread_extend对象,然后启动 Thread_extend t
=new Thread_extend(); t.start(); } }

2.创建多线程——实现Runnable接口

这种方法是常用的,因为继承只能继承一个类,接口可以实现多个。

class Thread_implements implements Runnable{
  //重写run方法
public void run(){ System.out.println("This is Thread"); } } class Thread_start{ public static void main(String[] args){
     //创建一个Thread_implments对象 Thread_implements t
=new Thread_implements();
     //这时候必须用线程的start方法才能启动一个新的线程,创建Thread对象时把t传进去,然后启动
new Thread(t).start(); } }

3.创建多线程——匿名类

继承Thread类,然后使用匿名类,直接在run方法里面写业务代码。然后直接启动这个匿名类。

public class Thread_anonymous{
    public static void main(String[] args){
        Thread t1=new Thread(){
          public void run(){
              System.out.println("This is Thread");
          }
        };
        t1.start();
    }
}

 

启动线程需要调用start()方法。run()方法并不能启动一个新线程,只是在线程启动后执行里面的代码。

 

4.常见的线程方法

1.暂停当前线程

public class Thread_anonymous{
    public static void main(String[] args){
        Thread t1=new Thread(){
          public void run(){
              //暂停1秒
              Thread.sleep(1000);
              System.out.println("This is Thread");
          }
        };
        t1.start();
    }
}   

2.加入当前线程

class thread_demo2 extends Thread {
    public static void main(String[] args){
        Thread t1= new Thread(){
            public void run(){
                for(int i=0;i<5;i++) {
                    System.out.println("This is t1");
                }
            }
        };
        Thread t2= new Thread(){
            public void run(){
                for(int i=0;i<5;i++) {
                    System.out.println("This is t2");
                }
            }
        };
        t1.start();
        t2.start();
    }
}

上面代码输出的是

This is t1
This is t2
This is t2
This is t2
This is t2
This is t2
This is t1
This is t1
This is t1
This is t1

如果在后面启动中间加上join

class thread_demo2 extends Thread {
    public static void main(String[] args) throws InterruptedException {
        Thread t1= new Thread(){
            public void run(){
                for(int i=0;i<5;i++) {
                    System.out.println("This is t1");
                }
            }
        };
        Thread t2= new Thread(){
            public void run(){
                for(int i=0;i<5;i++) {
                    System.out.println("This is t2");
                }
            }
        };
        t1.start();
        t1.join();
        t2.start();
    }
}

结果会变成

This is t1
This is t1
This is t1
This is t1
This is t1
This is t2
This is t2
This is t2
This is t2
This is t2

这里需要注意的是:并不是join让t2线程暂停,而是main线程暂停了,这时候t2线程还没启动,必须等待t1线程执行完毕main线程才能执行。

所以造成了一种t2让t1的错觉。所以join只是让main线程进入了等待池,其他线程没有受到影响。

我们再改一下代码:

class thread_demo2 extends Thread {
    public static void main(String[] args) throws InterruptedException {
        Thread t1= new Thread(){
            public void run(){
                for(int i=0;i<5;i++) {
                    System.out.println("This is t1");
                }
            }
        };
        Thread t2= new Thread(){
            public void run(){
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for(int i=0;i<5;i++) {
                    System.out.println("This is t2");
                }
            }
        };
        t1.start();
        t2.start();
    }
}

结果依旧是t1先执行完毕,t2再执行。

结合上面的实验,得出总结

join方法会暂停当前线程(并不会影响其他线程),并让调用这个方法的线程优先执行,只有当这个线程执行完毕,暂停线程才能执行。如果join没有写在任何线程里面,那么就是暂停java默认的main线程。

3.守护线程

一个进程里面有很多个线程,当一个进程里面只剩下守护线程时,进程会自动结束。守护线程优先级较低,常用于日志之类的功能。

public class Thread_anonymous{
    public static void main(String[] args){
        Thread t1=new Thread(){
          public void run(){
              //暂停1秒
              Thread.sleep(1000);
              System.out.println("This is Thread");
          }
        };
        //设置当前线程为守护线程
        t1.setDaemon(true);
        t1.start();
    }
}   

4.线程优先级

优先级高的线程会有更大的几率获得CPU资源

public class Thread_anonymous{
    public static void main(String[] args){
        Thread t1=new Thread(){
          public void run(){
              System.out.println("This");
          }
        };
        
        Thread t2=new Thread(){
            public void run(){
                System.out.println("This");
            }
        };
         //设置线程优先级
        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.MIN_PRIORITY);
        t1.start();
        t2.start();
    }
}   

5.临时暂停

临时暂停当前线程,使其他线程有更大几率获得CPU资源。

public class Thread_anonymous{
    public static void main(String[] args){
        Thread t1=new Thread(){
          public void run(){
              System.out.println("This");
          }
        };
        
        Thread t2=new Thread(){
            public void run(){
                //临时暂停当前线程,虽然t1t2优先级一样,但是t1可以占用CPU资源
                Thread.yield();
                System.out.println("This");
            }
        };
         //设置线程优先级
        t1.setPriority(3);
        t2.setPriority(3);
        t1.start();
        t2.start();
    }
}   

 

posted @ 2019-10-22 21:56  LingCode丶  阅读(346)  评论(0编辑  收藏  举报