Java多线程

Author: Abbott Liu(刘建)

Education: 加里敦

所谓多线程,就是说一个应用程序有多条执行路径,每当我们打开一个应用程序的时候,就像当与打开了一个进程,而进程中执行的操作,就是线程。以迅雷为例,打开迅雷就相当于打开一个进程,下载文件的操作就是线程,多线程就是同时下载多个文件

在Java中有两种方式实现多线程分别是继承Thread类和实现Runnable接口

一、继承Thread类

Thread类中有一个run方法,但是这个run方法需要我们重写,故我们需要自定义一个类来继承Thread类,然后在自定义的类中重写这个run方法,重写完了就可以创建一个对象了,用该对象去调用这个方法,但是由于这是多线程,如果是直接调用run方法,无法实现多线程,然后就有了一个新的的方法start方法供我们使用,此方法会自动调用run方法。

代码:

package com.abbott;

class MusicThread extends Thread {
    public void run() {
        for (int x = 0; x < 10; x++) {
            System.out.println(getName() + ":" + x);
        }
    }
}

public class MultiplyThread {
    public static void main(String[] args) {

        //创建多线程对象
        MusicThread mt1 = new MusicThread();
        MusicThread mt2 = new MusicThread();
        MusicThread mt3 = new MusicThread();

        //设置每个对象的名字
        mt1.setName("abbott");
        mt2.setName("liu");
        mt3.setName("java");

        // 调用start()方法,其内部调用了run()方法,实现了多线程
        // 如果直接调用run()方法,不能实现多线程
        mt1.start();
        mt2.start();
        mt3.start();

    }
}

二、实现Runnable接口

为了解决单继承的局限性,因为如果某个类已经有父亲了,那么它就不能再继承Thread来实现多线程了,所以就有了实现接口的多线程,我们大部分使用的方法也是用接口来实现多线程。接口方式实现多线程我们需要自定义一个类去实现Runnable接口,然后在自定义的类中重写run方法,再然后去创建一个自定义类的对象,最后创建一个Thread类的对象,并且把刚刚创建的自定义对象作为参数传递。

package com.abbott;

class Father {
    private String name = "刘建";

    public String getName() {
        return name;
    }
}

class MusicThread extends Father implements Runnable {
    static int count = 0;
    //公共资源

    private int t = 0;

    private synchronized void increase() {
        count++;
    }

    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            increase();
            System.out.println(Thread.currentThread().getName() + ":" + count);
//            System.out.println(Thread.currentThread().getName() + ":" + t++);
        }
    }
}

public class MultiplyThread {
    public static void main(String[] args) throws InterruptedException {

        //创建多线程对象
        MusicThread mt = new MusicThread() ;

        Thread t1 = new Thread(mt,"abbott");
        Thread t2 = new Thread(mt,"liu");
        Thread t3 = new Thread(mt,"hello");

        //设置每个对象的名字
        t1.start();
        t2.start();
        t3.start();

    }
}

三、继承Thread类和实现Runnable方法的区别

  • 继承Thread类不适合资源的共享,而实现Runnable接口很容易实现资源的共享
  • 实现Runnable接口适合多个相同的程序代码的线程去处理同一个资源
  • 避免了Java中的单继承限制
  • 增强了程序的健壮性,代码可以被多个线程共享

四、线程延时sleep()

package com.abbott;

class Father {
    private String name = "刘建";

    public String getName() {
        return name;
    }
}

class MusicThread extends Father implements Runnable {
    static int count = 0;
    //公共资源

    private int t = 0;

    private synchronized void increase() {
        count++;
    }

    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            increase();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + ":" + count);
//            System.out.println(Thread.currentThread().getName() + ":" + t++);
        }
    }
}

public class MultiplyThread {
    public static void main(String[] args) throws InterruptedException {

        //创建多线程对象
        MusicThread mt = new MusicThread() ;

        Thread t1 = new Thread(mt,"abbott");

        t1.start();

    }
}

五、线程中断interrupt()

package com.abbott;

class MusicThread extends Thread {

    public void run() {
        System.out.println("线程开始");
        try {
            // 在这里是线程休息2秒,如果线程在2秒内被中断,则执行catch
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // e.printStackTrace();
            System.out.println("线程中断");
        }
        System.out.println("线程结束");
    }
}

public class MultiplyThread {
    public static void main(String[] args) throws InterruptedException {

        MusicThread mt = new MusicThread();

        mt.start();
        try {
            Thread.sleep(1000);
            mt.interrupt();// 这里的意思是线程执行如果超过1秒就被中断
        } catch (InterruptedException e) {
            // e.printStackTrace();
            System.out.println("中断线程");
        }

    }
}

六、线程同步synchronized()

多线程中,线程同步问题

package com.abbott;

class Father {
    private String name = "刘建";

    public String getName() {
        return name;
    }
}

class MusicThread extends Father implements Runnable {
    static int count = 0;
    //公共资源

    private int t = 0;

    private synchronized void increase() {
        count++;
    }

    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            increase();
            System.out.println(Thread.currentThread().getName() + ":" + count);
//            System.out.println(Thread.currentThread().getName() + ":" + t++);
        }
    }
}

public class MultiplyThread {
    public static void main(String[] args) throws InterruptedException {

        //创建多线程对象
        MusicThread mt = new MusicThread() ;

        Thread t1 = new Thread(mt,"abbott");
        Thread t2 = new Thread(mt,"liu");
        Thread t3 = new Thread(mt,"hello");

        //设置每个对象的名字
        t1.start();
        t2.start();
        t3.start();

    }
}

六子
393 声望2 粉丝