久染

导航

Java day20 高级编程【第一章】Java多线程编程

【第一章】Java多线程编程

一.进程与线程

    多个时间段会有多个程序依次执行,但是同一时间点只有一个进程执行

    线程是在进程基础之上划分的更小的程序单元 ,线程是在进程基础上创建并且使用的,所以线程依赖于进程的支持,但是来讲,线程的启动速度要比进程快许多,所以使用多线程进行并发处理的时候,执行的性能要高于进程。

二.Thread类实现多线程

    如果想要在JAVA中实现多进程,就必须有一个专门的线程类进行线程执行任务的定义,而这个主体类的定义是有要求的,必须实现特定的接口或者继承特定的父类才可以完成。

1.继承Thread类实现多线程

    java里面提供有一个java.lang.Thread的一个程序类,一个类只要继承了此类,并且覆写了Thread类中提供的run()方法,就表示这个类是线程的主体类,而这个方法就是线程的主方法。

范例:多线程主体类:

class Mythread extends Thread{                //线程主体类
    private String title;
    public Mythread(String title) {
        this.title = title;
    }
    @Override
    public void run() {                                        //线程主体方法
        for (int x = 0; x<10;x++) {
            System.out.println(this.title + "运行 x =" + x);
        }
    }
    
}

 

  多线程要执行的功能都应该在run()方法中定义。需要说明的是,run方法不能够被直接调用,因为这里面牵扯到一个操作系统的资源调度问题

,所以要想启动多线程,必须使用start方法。

        new Mythread("线程A").start();
        new Mythread("线程B").start();
        new Mythread("线程C").start();

  在java程序执行的过程之中考虑到对于不同层次开发者的需求,所以支持有本地的操作系统函数调用,这个技术被称为JNI(Java Native Interface Java本地接口)技术,而java中不推荐这样使用。

而在Thread类里提供的start0()就表示需要将此方法依赖于不同的操作系统实现。

public synchronized void start() {
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
    group.add(this);

    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {

        }
    }
}
    private native void start0();

 

疑问:为什么必须使用start而不能使用run方法:

 

 

   任何情况下只要定义了多线程,多线程的启动永远只有一种方案:Thread类中的start方法。

三.Runnable接口实现多线程

  虽然可以通过Thread类的继承来实现多线程的定义,但是在java程序中对于继承永远都是存在有单继承局限的,所以在java又提供了第二种多线程的主体定义形式:

实现java.lang.Runnable,此接口定义如下:

 

@FunctionalInterface
public void  Runnable() {
    public void run();
}

 

范例:通过Runnable实现多线程(Thread​(Runnable target)):

class Mythread implements Runnable{                //线程主体类
    private String title;
    public Mythread(String title) {
        this.title = title;
    }
    @Override
    public void run() {                                        //线程主体方法
        for (int x = 0; x<10;x++) {
            System.out.println(this.title + "运行 x =" + x);
        }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Thread threada = new Thread(new Mythread("线程对象A"));        
        Thread threadb = new Thread(new Mythread("线程对象B"));        
        Thread threadc = new Thread(new Mythread("线程对象C"));        
        threada.start();
        threadb.start();
        threadc.start();
    }

  由于此时只是实现了Runnable接口对象,此时线程主体就不再有单继承的局限,这样的设计才是标准的设计。

  Runnable接口使用了函数式接口的定义,所以也可以直接使用Lambda表达式进行线程类实现。

范例:利用Lambda实现多线程定义:

public class ThreadDemo {
    public static void main(String[] args) {
        for(int x = 0 ;x < 3 ; x++) {
            String title = "线程对象-" + x;
            Runnable run = ()->{
                for(int y = 0; y < 3 ; y++) {
                    System.out.println(title + "运行 x =" + x);
                }
            };
            new Thread(run).start();
        }
    }
}

  在以后开发之中对于对线程的实现,优先考虑的就是Runnable接口实现,并且都是通过Thread启动多线程

posted on 2019-11-10 17:55  久染  阅读(201)  评论(0编辑  收藏  举报