Java多线程基础

 更新时间:2021年10月27日 14:55:48   作者:冬日毛毛雨  
这篇文章主要介绍Java多线程基础,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位,多线程指在单个程序中可以同时运行多个不同的线程执行不同的任务,下面来学习具体的详细内容

一、线程

什么是线程:

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

什么是多线程:

多线程指在单个程序中可以同时运行多个不同的线程执行不同的任务。

二、创建多线程的方式

多线程的创建方式有三种:ThreadRunnableCallable

1、继承Thread类实现多线程

      Thread thread = new Thread() {
            @Override
            public void run() {
                super.run();
                while (true) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("1:" + Thread.currentThread().getName());
                    System.out.println("2:" + this.getName());
                }
            }
        };
        thread.start();

2、实现Runnable接口方式实现多线程

Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("3:" + Thread.currentThread().getName());
                }
            }
        });
        thread1.start();

3、Callable接口创建线程

public class CallableTest {

    public static void main(String[] args) {
        System.out.println("当前线程是:" + Thread.currentThread());
        Callable myCallable = new Callable() {
            @Override
            public Integer call() throws Exception {
                int i = 0;
                for (; i < 10; i++) {

                }
                //当前线程
                System.out.println("当前线程是:" + Thread.currentThread()
                        + ":" + i);
                return i;
            }
        };
        FutureTask<Integer> fu = new FutureTask<Integer>(myCallable);
        Thread th = new Thread(fu, "callable thread");

        th.start();

        //得到返回值
        try {
            System.out.println("返回值是:" + fu.get());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

当前线程是:Thread[main,5,main]
当前线程是:Thread[callable thread,5,main]:10
返回值是:10

总结:

实现Runnable接口相比继承Thread类有如下优势:

  • 可以避免由于Java的单继承特性而带来的局限;
  • 增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;
  • 适合多个相同程序代码的线程区处理同一资源的情况。

实现Runnable接口和实现Callable接口的区别:

  • Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
  • Callable规定的方法是call() , Runnable规定的方法是run()
  • Callable的任务执行后可返回值,而Runnable的任务是不能返回值是(void)
  • call方法可以抛出异常,run方法不可以
  • 运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
  • 加入线程池运行,Runnable使用ExecutorServiceexecute方法,Callable使用submit方法。

三、线程的生命周期与状态

四、线程的执行顺序

Join线程的运行顺序

原理:

1、定时器

import java.util.Timer;
import java.util.TimerTask;

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

//         new Timer().schedule(new TimerTask() {
//             @Override
//             public void run() {
//
//                 System.out.println("bombing!");
//             }
//         },10000);

        class MyTimberTask extends TimerTask {
            @Override
            public void run() {

                System.out.println("bombing!");
                new Timer().schedule(new MyTimberTask(), 2000);
            }
        }


        new Timer().schedule(new MyTimberTask(), 2000);


        int count = 0;
        while (true) {
            System.out.println(count++);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

0
1
bombing!
2
3
bombing!
4
5
bombing!
6
省略...

2、线程的互斥与同步通信

public class TraditionalThreadSynchronized {

    public static void main(String[] args) {

        new TraditionalThreadSynchronized().init();
    }

    private void init() {
        final Outputer outputer = new Outputer();

        new Thread(new Runnable() {
            @Override
            public void run() {

                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.output("kpioneer");

                }
            }
        }).start();

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//                while (true) {
//                    try {
//                        Thread.sleep(10);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    outputer.output2("Tom");
//
//                }
//            }
//        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {

                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.output3("Jack");

                }
            }
        }).start();
    }

  static   class Outputer {

        public void output(String name) {

            int len = name.length();

            synchronized (Outputer.class) {

                for (int i = 0; i < len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }

        }

        public synchronized void output2(String name) {
            int len = name.length();

            for (int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }

      public static synchronized void output3(String name) {
          int len = name.length();

          for (int i = 0; i < len; i++) {
              System.out.print(name.charAt(i));
          }
          System.out.println();
      }
    }
}

3、线程同步通信技术

子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程有循环100,如此循环50次,请写出程序。

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

        final Business business = new Business();
        new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 1; i <= 50; i++) {
                            business.sub(i);
                        }
                    }
                }
        ).start();
        for (int i = 1; i <= 50; i++) {
            business.main(i);
        }
    }

}

/**
 *要用到共同数据(包括同步锁)的若干方法应该归在同一个类身上,
 * 这种设计正好体现了高类聚和和程序的健壮性
 */
class Business {
    private boolean bShouldSub = true;
    public synchronized void sub(int i) {
        if(!bShouldSub) {

            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int j = 1; j <= 10; j++) {
            System.out.println("sub thread sequece of " + j + ",loop of " + i);

        }
        bShouldSub = false;
        this.notify();
    }

    public synchronized void main(int i) {
        if(bShouldSub) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int j = 1; j <=100; j++) {
            System.out.println("main thread sequece of " + j + ",loop of " + i);

        }
        bShouldSub = true;
        this.notify();
    }
}

sub thread sequece of 1,loop of 1
sub thread sequece of 2,loop of 1
sub thread sequece of 3,loop of 1
sub thread sequece of 4,loop of 1
sub thread sequece of 5,loop of 1
sub thread sequece of 6,loop of 1
sub thread sequece of 7,loop of 1
sub thread sequece of 8,loop of 1
sub thread sequece of 9,loop of 1
sub thread sequece of 10,loop of 1
main thread sequece of 1,loop of 1
main thread sequece of 2,loop of 1
main thread sequece of 3,loop of 1
main thread sequece of 4,loop of 1
main thread sequece of 5,loop of 1
main thread sequece of 6,loop of 1
main thread sequece of 7,loop of 1
main thread sequece of 8,loop of 1
main thread sequece of 9,loop of 1
main thread sequece of 10,loop of 1
main thread sequece of 11,loop of 1
省略中间...
main thread sequece of 99,loop of 1
main thread sequece of 100,loop of 1
sub thread sequece of 1,loop of 2
sub thread sequece of 2,loop of 2
sub thread sequece of 3,loop of 2
sub thread sequece of 4,loop of 2
sub thread sequece of 5,loop of 2
sub thread sequece of 6,loop of 2
sub thread sequece of 7,loop of 2
sub thread sequece of 8,loop of 2
sub thread sequece of 9,loop of 2
sub thread sequece of 10,loop of 2
main thread sequece of 1,loop of 2
main thread sequece of 2,loop of 2
main thread sequece of 3,loop of 2
省略...

到此这篇关于Java多线程基础的文章就介绍到这了,更多相关Java多线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java单链表的增删改查与面试题详解

    Java单链表的增删改查与面试题详解

    单链表是链表的其中一种基本结构。一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。 因为只有一个指针结点,称为单链表
    2022-09-09
  • Scala中优雅的处理Null问题

    Scala中优雅的处理Null问题

    Spark 采用混合方式,大部分情况下使用 Option,但个别时候出于性能原因才使用了null。一个很好的习惯是当有方法返回值可能为null的时候,使用Option来代替,本文给大家介绍Scala处理Null的知识详解,一起看看吧
    2021-08-08
  • 浅谈Spring中的循环依赖问题与解决方案

    浅谈Spring中的循环依赖问题与解决方案

    这篇文章主要介绍了浅谈Spring中的循环依赖问题与解决方案,循环依赖就是两个或则两个以上的bean互相持有对方,最终形成闭环,比如A依赖于B,B依赖于C,C又依赖于A,需要的朋友可以参考下
    2023-12-12
  • 详解关于springboot-actuator监控的401无权限访问

    详解关于springboot-actuator监控的401无权限访问

    本篇文章主要介绍了详解关于springboot-actuator监控的401无权限访问,非常具有实用价值,有兴趣的可以了解一下
    2017-09-09
  • springboot中使用mybatisplus自带插件实现分页的示例代码

    springboot中使用mybatisplus自带插件实现分页的示例代码

    这篇文章主要介绍了springboot中使用mybatisplus自带插件实现分页,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • springboot框架阿里开源低代码工具LowCodeEngine

    springboot框架阿里开源低代码工具LowCodeEngine

    这篇文章主要为大家介绍了springboot框架阿里开源低代码LowCodeEngine工具使用详解有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 使用Spring boot + jQuery上传文件(kotlin)功能实例详解

    使用Spring boot + jQuery上传文件(kotlin)功能实例详解

    本文通过实例代码给大家介绍了使用Spring boot + jQuery上传文件(kotlin) 功能,需要的朋友可以参考下
    2017-07-07
  • Springboot整合Rabbitmq之Confirm和Return机制

    Springboot整合Rabbitmq之Confirm和Return机制

    这篇文章主要介绍了Springboot整合Rabbitmq之Confirm和Return详解,本篇重点进行Confirm 机制和Return 机制的实现和说明,通过实例代码相结合给大家详细介绍,对Springboot整合Rabbitmq相关知识感兴趣的朋友一起看看吧
    2022-02-02
  • springboot集成shiro权限管理简单实现

    springboot集成shiro权限管理简单实现

    这篇文章主要介绍了springboot集成shiro权限管理简单实现,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • Spring+Quartz实现动态任务调度详解

    Spring+Quartz实现动态任务调度详解

    这篇文章主要介绍了Spring+Quartz实现动态任务调度详解,最近经常基于spring boot写定时任务,并且是使用注解的方式进行实现,分成的方便将自己的类注入spring容器,需要的朋友可以参考下
    2024-01-01

最新评论