JavaSE——线程安全

线程安全

我们在了解线程之前我们首先要了解线程产生的原因是什么?
在最早的时候,电脑只能进行单任务的模式运行,即同一时刻内电脑只运行一个软件,而这样便会在成大量的系统空间早成浪费,于是人们便想着如何才能让电脑在同一时刻内多个软件同时运行,即多任务。
但在多核CPU产生之前,CPU只能在同一时刻干一件事,所以在单核CPU下是不存在真正的多任务的。
多任务的概念:
并发:多个任务抢占资源
并行:多个任务同时运行
进程(process):操作系统运行和管理资源的基本单位!!!从操作系统核心角度来说,进程是操作系统调度和分配内存资源,CPU时间片的基本单位,它为正在运行应用程序提供了运行环境。简单来说,进程是应用程序的一次运行活动。
线程(Thread):操作系统运行和调度管理资源的最小单位!!!线程是程序内部的一个顺序代码流,它是CPU调度资源的最基本单位。
协程(Coroutines):轻量级的线程
注意:
在大多数的编程语言中,都是有以下三种实现多任务的方案:
多进程(muitl process)
多线程(mutil thread)
协程(Coroutines)

多线程:

多线程的概念:
多线程就是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率。线程是在同一时间需要完成多项任务的时候被实现的。
什么是并行、并发和高并发:
并行:同时运行多条线程,就是并行
并发 :在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
高并发简单点说:就是在同一时刻不同用户访问同一资源的问题,专业一点的说法就是在同一时刻有多个线程访问了同一个数据资源。
Java中实现多线程的方案:
继承Thread类:

public class TestThread02 {
    public static void main(String[] args) {
        //创建线程对象,
        MyThread mt = new MyThread();
        //使用start方法启动线程
        mt.start();
        while (true){
            System.out.println("我在唱歌");
        }
    }
}
class  MyThread extends Thread{
    @Override
    public void run(){
        while (true) {
            System.out.println("我在跳舞");
        }
    }
}

实现Runable接口:

public class TestRunable implements Runnable{
    public static void main(String[] args) {
        TestRunable tr =  new TestRunable();
        //借助thread类实现启动
        Thread task = new Thread(tr);

        task.start();
        while (true){
            System.out.println("我在唱歌");
        }
    }
    @Override
    public void run() {
        //线程方法
        while (true) {
            System.out.println("我在跳舞");
        }
    }
}

实现Callable接口和Future接口:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestCallable {
    public static void main(String[] args) {
        MyTable3 mt3 = new MyTable3();
        FutureTask future = new FutureTask(mt3);
        //启动线程
        new Thread(future).start();
        for (int i = 0; i < 100; i++) {
            System.out.println("---------main----------");
        }
        //使用FutureTask对象的get方法获取子线程运行后的结果
        try {
            System.out.println("子线程执行完成后的返回结果" + future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
//Callable实现多线程,支持泛型,也可以返回一个改泛型对应的值
class MyTable3 implements Callable<Integer> {
    //call就是线程方法
    @Override
    public Integer call() throws Exception {
        int count = 0;
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+ "开始运行了");
            count++;
        }
        return count;
    }
}

线程安全

线程安全的概念:
线程安全指的是多线程的安全。如果一段程序可以保证被多线程访问后仍能保持正确性,那么程序就是线程安全的。一般来说,线程安全注重的是多线程开发中的共享数据的安全。
这就是非线程安全的:
在这里插入图片描述
这是线程安全的:
在这里插入图片描述
产生非线程安全的原因:
必须要存在两个或者两个以上的线程共享着一个资源。
操作共享资源的代码必须有两句或者两句以上。
解决方案:

  1. 同步代码块
    synchronized(锁){
    需要被同步的代码
    }

    1. 同步函数。
      修饰符 synchronized 返回值类型 函数名(形参列表…){
      }
      注意:
      1. 同步代码块的锁可以是任意的对象。 同步函数的锁是固定 的,非静态函数的锁对象是this对象。 静态函数的锁对象是class对象。
      2. 锁对象必须是多线程共享的对象,否则锁不住。
      3. 在同步代码块或者是同步函数中调用sleep方法是不会释放锁对象的,如果是调用了wait方法是会释放锁对象的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值