Java多线程与并发概念简要

基本概念

程序

是为了完成特定任务、用某种语言编写的一组指令的集合

进程

线程是程序的一次执行过程,进程是执行的程序
进程是资源分配的单位

线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
每个线程拥有独立的运行栈和程序计数器
一个Java应用程序java.exe,最少有三个线程:main()主线程,gc()垃圾回收线程,异常处理线程。

并行

多个cpu同时执行多个任务。

并发

一个cpu同时执行多个任务。

多线程的四种实现方式

继承 Thread类并重写run()

package multiThread;
public class ByThread extends Thread{
    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            System.out.println("新线程:"+i);
            try {
                 sleep(10);
            } catch (InterruptedException e) {
                 e.printStackTrace();
            }
        } 
    }
    public static void main(String[] args) throws InterruptedException {
        ByThread byThread = new ByThread();
        byThread.start();
        for(int i = 0; i < 10; i++){
            System.out.println("主线程线程:"+i);
            sleep(10);
        }
    }
}

实现Runnable接口重写run()

package multiThread;

public class ByRunnable implements Runnable{
    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.currentThread().sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ByRunnable byRunnable = new ByRunnable();
        new Thread(byRunnable).start();
        for(int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName());
            Thread.currentThread().sleep(10);
        }
    }
}

实现Callable接口重写call方法

package multiThread;

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

public class ByCallable implements Callable {
    @Override
    public Object call() throws Exception {
        for(int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.currentThread().sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    public static void main(String[] args){
        ByCallable byCallable = new ByCallable();
        FutureTask futureTask = new FutureTask(byCallable);
        new Thread(futureTask).start();

        for(int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.currentThread().sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

同步代码块
synchronized(同步监视器){
//需要被同步的代码

}
  1. 操作共享数据的代码即为需要被同步的代码。
  2. 共享数据:带哦个线程共同操作的变量。比如:ticket就是共享数据。
  3. 同步监视器,俗称:所。仍和一个类的对象都可以充当锁。要求:多个线程必须要共用一把锁。
  4. 同步的方式,解决了线程的安全问题。—好处
  5. 操作同步代码块时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。–坏处
同步方法

默认的同步监视器默认为:this
当使用的线程类不唯一但操作的数据唯一时,需要将同步方法改为静态方法。

lock

需要手动实例化 lock, 手动锁定lock,手动解锁

JDK1.5新增,建议优先使用Lock

Lock -> 同步代码块 -> 同步方法

volatile

volatile修饰符适用于以下场景:
某个属性被多个线程共享,其中有一个线程修改了此属性,其他线程可以立即得到修改后的值,比如booleanflag;或者作为触发器,实现轻量级同步。
volatile属性的读写操作都是无锁的,它不能替代synchronized,因为它没有提供原子性和互斥性。因为无锁,不需要花费时间在获取锁和释放锁_上,所以说它是低成本的。
volatile只能作用于属性,我们用volatile修饰属性,这样compilers就不会对这个属性做指令重排序。volatile提供了可见性,任何一个线程对其的修改将立马对其他线程可见,volatile属性不会被线程缓存,始终从主 存中读取。
volatile提供了happens-before保证,对volatile变量v的写入happens-before所有其他线程后续对v的读操作。
volatile可以使得long和double的赋值是原子的。volatile可以在单例双重检查中实现可见性和禁止指令重排序,从而保证安全性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值