Java-多线程

博文仅为学习记录,仅供参考


Java-多线程
1.概念

进程:正在运行的程序

线程:进程中的单个顺序控制流,是一条执行路径。

  • 单线程:一个进程只有一条执行路径
  • 多线程:一个进程有多条执行路径
2.实现多线程

Thread类:public class Thread extends Object implements Runnable

继承关系:

java.lang.Object
 java.lang.Thread

jdk文档中的说明:

线程是程序中执行的线程。Java虚拟机允许应用程序同时执行多个执行线程。

每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在一些线程中运行的代码创建一个新的Thread对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。

当Java虚拟机启动时,通常有一个非守护进程线程(通常调用某个指定类的名称为main的方法)。 Java虚拟机将继续执行线程,直到发生以下任一情况:

  • 该exit类的方法Runtime已经被调用并且安全管理器允许退出操作发生。
  • 不是守护进程线程的所有线程都已经死亡,无论是从调用返回到run方法还是抛出异常,传播超出了run方法。

创建一个新的执行线程有两种方法。 一个是将一个类声明为一个Thread的子类。 这个子类应该重写Thread类的方法run()。 然后可以分配并启动子类的实例。创建线程的另一种方法是声明一个实现Runnable接口的类,然后那个类实现了run方法。

构造方法:

  • public Thread():分配一个新的线程对象
  • public Thread(String name):分配一个指定名称的新线程对象
  • public Thread(Runnable target):分配一个带指定目标的新线程对象
  • public Thread(Runnable target,String name):分配一个带指定目标、指定名称的新线程对象

常用方法:

  • public String getName():获取当前线程名称
  • public void run():此线程要执行的任务在这里面定义
  • public void start():让此线程开始执行,Java虚拟机调用此线程的run()方法
  • public static void sleep(long mills):使当前正在执行的线程以指定的毫秒数暂停
  • public static Thread currentThread():返回对当前正在执行的线程对象的引用

先使用继承Thread类的方法实现多线程:

MyThread类:

public class MyThread extends Thread{
    //重写run()方法
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            //Thread类中有两个方法:getName()和setName(),用来获取和设置进程名称
            System.out.println(this.getName()+":"+i);
        }
    }
}

测试类Main:

public class Main {

    public static void main(String[] args) {
        MyThread mt1=new MyThread();
        MyThread mt2=new MyThread();
        //设置名称
        mt1.setName("线程a");
        mt2.setName("线程b");
        mt1.start();
        mt2.start();

    }
}

编译运行,控制台输出:

线程a:0
线程a:1
线程a:2
线程a:3
线程a:4
线程a:5
线程b:0
线程b:1
线程a:6
线程b:2
线程a:7
线程a:8
线程a:9
线程b:3
……

(上面省略号是略过后面的输出)

在MyThread类中重写了run()方法,在里面将整数1-100打印到控制台,在main()方法里面创建MyThread实例mt1和mt2,并分别设置它们的名称,然后分别执行mt1.start()和mt2.start(),start()这个方法就是启动一个新的线程,并执行这个对象里面的run()方法。从输出可以看出,虽然在main()里面是先执行mt1.start()然后再执行mt2.start(),但是并不是等mt1的run()执行完毕再执行mt2的run(),而是两个run()方法是没有规律地交错执行的。

多线程的意义:不同的线程在不同的栈空间,它们的执行互不影响。

下面使用第二种方式实现多线程:实现Runnable接口。

步骤:

  1. 创建一个类实现Runnable接口

  2. 在这个类中重写run()方法,设置线程任务

  3. 创建类的对象

  4. 创建Thread类对象,在构造方法中将实现类的对象引用传进去

  5. 调用Thread类对象的start()方法

范例:

MyThread01类:

public class MyThread01 implements Runnable{
    @Override
    public void run() {
        for (int i=0;i<50;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }

    }
}

TestMain类:

public class TestMain {
    public static void main(String[] args) throws InterruptedException {
        //创建Runnable接口的实现类对象,命名为mt
        MyThread01 mt = new MyThread01();
        //创建Thread类对象,将mt作为构造方法的参数
        Thread t = new Thread(mt);
        //执行t的start()方法
        t.start();

        for (int i = 0; i < 50; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }

    }
}

编译运行,控制台输出:

main:0
main:1
main:2
Thread-0:0
main:3
Thread-0:1
main:4
Thread-0:2
main:5
Thread-0:3
main:6
……

(上面省略号是略过后面的输出)

3.两种实现多线程的方式的区别

相比之下,使用实现Runnable接口的方式来创建多线程程序是比使用直接继承Thread类的方式有更多的优势:

  1. 避免了单继承的局限性:一个类只能继承一个父类,如果一个类继承了Thread类就不能再继承其他的类,如果使用实现Runnable接口的方式,则可以继承其他的类。
  2. 增强了程序的扩展性,降低了程序的耦合性:使用实现Runnable接口的方式,将设置线程任务和开启新线程进行分离(解耦),在实现类中重写run()方法,用来设置线程任务;创建Thread类对象,调用start方法,用来开启新的线程。
4.匿名内部类实现多线程

范例:

public class Main01 {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                this.setName("线程1");
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }

            }
        }.start();

        Runnable r=new Runnable(){
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
        };
        new Thread(r,"线程2").start();
    }
}

编译运行,控制台输出:

线程1:0
线程1:1
线程2:0
线程2:1
线程2:2
线程1:2
线程2:3
线程1:3
线程2:4
……

(上面的“……”为后面输出的省略)

使用匿名内部类创建对象实现多线程的好处是:方便创建不同的线程来执行不同的任务,简化代码。


博文仅为学习记录,仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值