Java(多线程)

一、基本概念

  1. 进程:一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
  2. 线程 :操作系统中能够进行运算的最小单位,它被包含在进程 之中,是进程中的实际运作单位。(简单理解:应用软件中相互独立,可以同时运行的功能)
  • 多线程:

作用:提高效率

应用场景:多件事情同时运行

3.并发并行

  • 并发:在同一时刻,有多个指令在CPU上交替执行
  • 并行:在同一时刻,有多个指令在CPU上同时执行

二、多线程实现方法

1.继承Thread类

  • 创建继承Thread的子类

  • 重写Thread类的run()方法

  • 创建Thread类的子类的对象。

  • 通过此对象调用start()来启动一个线程。

    public class MyThread extends Thread {
    public void run(){
    for (int i = 0; i < 100; i++) {
    System.out.println(getName()+"HelloWord");
    }
    }

      public static void main(String[] args) {
          MyThread t1 = new MyThread();
          MyThread t2 = new MyThread();
          t1.start();
          t2.start();
      }
    

    }

2.实现Runnable接口

  • 定义一个类实现Runnable接口

  • 重写里面的Run()方法

  • 创建自己的类的对象

  • 创建一个Thread类的对象调用start(),开起线程

    public class RunnableThread {
    public static void main(String[] args) {
    MyRun mr = new MyRun();
    Thread t1 = new Thread(mr);
    t1.start();
    Thread t2 = new Thread(mr);
    t2.start();
    }
    }

    class MyRun implements Runnable {
    @Override
    public void run() {
    for (int i = 1; i <= 100; i++) {
    System.out.println(Thread.currentThread().getName()+":/t"+i);
    }
    }
    }

3.利用Callable接口和Future接口(特点:可以获取到多线程运行的结果)

  • 创建一个类MyCallable实现callable接重写call (是有返回值的,表示多线程运行的结果)

  • 创建MyCallable的对象(表示多线程要执行的任务)

  • 创建FutureTask的对象(作用管理多线程运行的结果)

  • 创建Thread类的对象,并启动(表示线程)

三种方式对比:

三、常见的成员方法

四、线程的生命周期

线程的动态特征表明:它由创建而生,由调度而执行,由撤销而消亡。说明线程具有一个从生到死的生命周期。

**新建:**当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态

**就绪:**处于新建状态的线程被start()后,将进入线程队列等待cpu时间片,此时它已经具备了运行的条件

**运行:**当就绪的线程被调度并获得处理器资源时,便进入运行状态,run()方法定义了线程的操作和功能

**阻塞:**在某种特殊情况下,被人为挂起或者执行输入输出操作时,让出cpu并临时终止你自己的执行,进入阻塞状态

**死亡:**线程完成了它的全部工作或线程被提前强制性地中止

五、多线程安全性问题的解决

如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。 程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 线程安全问题都是由全局变量及静态变量引起的。 若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

解决方法:

1.同步代码块

  • 将操作共享的代码锁起来
  • 锁默认打开,有一个线程进去了,锁自动关闭
  • 里面的代码全部执行完毕,线程出来,锁自动打开
public class MyThread extends Thread {

    static int a = 0;
    static Object obj = new Object();
    public void run(){
        while(true){
            synchronized (obj){
                if(a<100){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    a++;
                    System.out.println(getName()+"卖第"+a);
                }
                else
                    break;

            }
        }
    }
}

public class Test {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

2.同步方法:

  • 将 synchronized关键字加在方法上
  • 锁住方法里的所有代码
  • 锁对象不能自己制定
  • 非静态的同步方法,同步监视器是:this
  • 静态的同步方法,同步监视器是:当前类的字节码文件对象
  • 格式:
相关推荐
姑苏风4 分钟前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生1 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程2 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*3 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue3 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man3 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang