java多线程与线程安全问题

本文详细讲解了Java中的多线程概念,包括进程与线程的区别、线程特点,以及如何通过继承Thread类和实现Runnable接口创建线程。此外,还探讨了线程安全问题,如在多线程环境下保证数据一致性,并举例说明了同步代码块的使用,以防止并发访问临界资源时的数据不一致。最后,对比了String、StringBuffer和StringBuilder在多线程场景下的使用区别。
摘要由CSDN通过智能技术生成

目录

一、多线程

1.1.进程与线程

1.2.进程与线程的区别

1.3.线程的特点

二、多线程详解

 2.1.java如何实现多线程?

2.2.创建线程方式

   2.2.1.继承Thread类并重写run方法。

2.2.2实现Runnable接口

三、Thread类中常用的方法

四、多线程安全问题

(1)需求: A线程将“Hello”存入数组;B数据将“World”存入数组。

 (2)在程序应用中,如何保证线程的安全性? 

五、拓展 

String、StringBuffer、StringBuilder的区别?


一、多线程

1.1.进程与线程

  • 进程:是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程。
  • 线程:线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程中⾄少有⼀个线程。⼀个进程中是可以有多个线程的,这个应⽤程序也可以称之为多线程程序。

      总之⼀个程序运⾏后⾄少有⼀个进程,⼀个进程中可以包含多个线程。

1.2.进程与线程的区别

  1.  进程是操作系统资源分配的基本单位,而线程是CPU的基本调度单位。
  2. 一个程序运行后至少有一个线程。
  3.  一个进程可以包含多个线程,但是至少需要有一个线程,否则这个进程是没有意义。
  4.  进程间不能共享数据段地址,但是同进程的线程之间可以。

1.3.线程的特点

  1. 线程抢占式执行 。

       (1)效率高;

       (2)   可防止单一线程长时间独占CPU;

     2. 在单核CPU中,宏观上同时执行,微观上顺序执行。

二、多线程详解

 2.1.java如何实现多线程?

  1. 继承Thread类,重写run方法
  2.  实现Runnable接口 
  3.  实现Callable接口

2.2.创建线程方式

   2.2.1.继承Thread类并重写run方法。

自定义线程类:

public class MyThread extends Thread{
    //1.重写run方法:现成的执行任务
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            System.out.println("i====================="+i);
        }
    }
}

 测试类:

public class Test01 {
    public static void main(String[] args) {
        //1.创建线程对象
        MyThread myThread = new MyThread();

        //2.开启线程 ---当获取到cpu时间片,那么该线程就会执行run方法的任何代码
        myThread.start();//多线程
        myThread.run();//一个线程,先执行run,在执行main

        for (int j = 0; j < 30; j++) {
            System.out.println("main================="+j);
        }
    }
}

运行结果:

  1. 获取当前线程的名称
  • 第一种: 通过父类Thread中的getName()可以获取线程名称。必须为Thread的子类
  • 第二种: 通过Thread类中的静态方法currentThread获取当前线程,getName()获取线程名。任意处获取线程名。

使用getName()取名

//1.继承Thread类
public class MyThread extends Thread{
    //2.重写run方法:现成的执行任务
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            System.out.println(getName()+"====================="+i);
        }
    }
}

使用Thread.currentThread().getName()取名:

public class Test01 {
    public static void main(String[] args) {
        //1.创建线程对象
        MyThread myThread1 = new MyThread("线程C");
        //2.开启线程 ---当获取到cpu时间片,那么该线程就会执行run方法的任何代码
        myThread1.start();//多线程
        //myThread.run();//一个线程,先执行run,在执行main

        //1.创建线程对象
        MyThread myThread2 = new MyThread("线程D");
        //2.开启线程 ---当获取到cpu时间片,那么该线程就会执行run方法的任何代码
        myThread2.start();//多线程

        for (int j = 0; j < 30; j++) {
            System.out.println(Thread.currentThread().getName()+"================="+j);
        }
    }
}

2 .为线程起名

 通过setName()为线程起名:

public class Test {
    public static void main(String[] args) {
        //1.创建线程对象
        MyThread myThread1 = new MyThread();
        myThread1.setName("线程A");
        //2.开启线程 ---当获取到cpu时间片,那么该线程就会执行run方法的任何代码
        myThread1.start();//多线程

        //1.创建线程对象
        MyThread myThread2 = new MyThread();
        myThread2.start("线程B");
        //2.开启线程 ---当获取到cpu时间片,那么该线程就会执行run方法的任何代码
        myThread2.start();

        for (int j = 0; j < 30; j++) {
   
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值