多线程的初步认识

 

目录

1、线程的概念

1.1 线程的注意事项

1.2 进程和线程的区别

2、线程的创建

2.1 继承Thread创建

2.2 实现Runnable创建

2.3 使用匿名内部类创建

2.4 使用lambda表达式

3、线程启动

4、线程终止

5、线程等待


 多线程是提升程序性能的一种非常重要的方式,使用多线程可以让程序充分利用CPU的资源,提高CPU的使用效率,从而解决高并发带来的负载均衡问题。

1、线程的概念

每个运行的程序都是一个进程,在一个进程中还可以有多个执行单元同时运行,这些执行单元就可以看作程序执行的一条条线索,称为线程。

操作系统中每一个进程中至少存在一个线程。

例如,当一个Java程序启动时,就会产生一个进程,该进程中会默认创建一个线程,在这个线程上会运行main()方法中的代码。

一个进程可以根据需要创建多个线程,从而实现”并发编程“的效果。

1.1 线程的注意事项

1、一个进程中是可以有多个线程的,每个线程都是可以独立进行调度的。

2、一个进程可以使用一个PCB表示,一个进程也可能使用多个PCB表示,每个PCB对应到每个线程上。

3、同一个进程的多个线程之间,共用一份内存空间和文件资源。

1.2 进程和线程的区别

1、进程包含线程,一个进程里面可以有多个线程。

2、进程和线程都是用来实现并发编程场景的,但是线程比进程更高效。

3、同一个进程的线程之间,共用一份的资源,省去了申请资源的开销。

4、进程和进程之间,具有独立性,不会相互影响。线程和线程之间,是可能会相互影响的。

5、进程是资源分配的基本单位,线程是调度执行的基本单位。


2、线程的创建

线程的创建主要有五种方式:

1、继承Thread,重写run

2、实现Runnable,重写run

3、继承Thread,重写run,使用匿名内部类

4、实现Runnable,重写run,使用匿名内部类

5、使用lambda

2.1 继承Thread创建

1、使用Thread这个类,可以创建Thread对象,进一步就可以创建操作系统内部的线程。

2、start和run都是Thread的成员,run只是描述了线程的入口(线程该做什么任务),start则是真正的调用了系统的API,在系统中创建了线程,再调用run。

3、在多线程中,main()方法和MyThread类的run()方法可以同时运行,互不影响。

4、可以使用sleep()方法来降低线程运行的速度。

class MyThread extends Thread{
    @Override
    public void run() {
        while (true) {

            System.out.println("hello Thread");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class demo {
    public static void main(String[] args) {
        Thread t=new MyThread();
        t.start();
        while (true){

            System.out.println("hello main");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

2.2 实现Runnable创建

通过继承Thread类实现多线程,具有一定的局限性。因为Java只支持单继承,一个类一旦继承了某个父类就无法再继承Thread类,就无法通过继承Thread类创建线程。

Thread类提供了另一个构造方法Thread(Runnable target),其中Runnable是一个接口,它只有run()方法。当通过Thread(Runnable target)构造方法创建线程对象时,只需要为该方法传递一个实现了Runnable接口的实例对象,就可以调用Runnable接口中的run()方法作为运行代码。

class MyRunnable implements Runnable{
    @Override
    public void run() {
        while (true){

            System.out.println("hello Runnable");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class demo{
    public static void main(String[] args) {
        Runnable runnable=new MyRunnable();
        Thread t=new Thread(runnable);
        t.start();
        while (true) {

            System.out.println("hello main");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

2.3 使用匿名内部类创建

使用匿名内部类创建就是将继承的Thread类和实现的Runnable类,写成一个匿名内部类,在一个类中创建。

继承Thread,重写run

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

        Thread t=new Thread(){

            public void run() {
                while (true) {
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        t.start();
        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

实现Runnable,重写run

public class demo{

    public static void main(String[] args) {

        Runnable runnable=new Runnable(){

            public void run() {
                while (true){
                    System.out.println("hello Runnable");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t=new Thread(runnable);
        t.start();
        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

2.4 使用lambda表达式

lambda表达式,本质上是一个匿名函数,主要实现”回调函数“的效果,让语法表达更加简化。

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

        Thread t=new Thread(()-> {

        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        });

        t.start();

        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3、线程启动

public class demo {

    public static boolean isQuit=false;

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

        Thread t=new Thread(()->{

           while (!isQuit){
               System.out.println("线程在工作中");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });

        t.start();

        Thread.sleep(5000);

        isQuit=true;

        System.out.println("线程工作结束");

    }

}

4、线程终止

Thread.currentThread()方法可以获取当前线程的实例

isInterrupted()方法调用Thread内部的标志位,根据这个标志位就可以判断线程是否结束

t.interrupt()方法把Thread对象内部的标准位设置为true

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

        Thread t=new Thread(()->{

           while (!Thread.currentThread().isInterrupted()){

               System.out.println("线程工作中");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });

        t.start();
        Thread.sleep(1000);
        System.out.println("让t线程中止");

        t.interrupt();
    }

}

5、线程等待

让一个线程等待另一个线程执行结束,再继续执行,本质上就是控制线程的顺序。

在主线程中调用t.join(),就是让主线程等待t线程先结束。

public class demo {

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

        Thread t = new Thread(() -> {

            for (int i = 0; i < 5; i++) {
                System.out.println("线程工作中");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t.start();

        System.out.println("join等待开始");

        t.join();

        System.out.println("join等待结束");

    }

}

t.join()的工作原理

1、如果t线程正在运行中,此时调用join的线程就会堵塞,一直阻塞到t线程执行结束为止

2、如果t线程已经执行结束了,此时调用join的线程,就会直接返回,不会涉及到堵塞


  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值