JAVA 并发Day1

jvm 在启动的时候就会启动很多线程, 

main  线程  gc 线程 jit 线程

https://www.cnblogs.com/jiangwangxiang/p/9094006.html

linux 之父, linus torvalds 对并行反对意见

并行计算只有在图像处理和服务端编程2个领域可以使用,并且它在这2个

领域确实有着大量广泛的使用

 

同步(synchronous)

异步 (asynchronous)

并发(Concurrency)

并行指的是不同线程通过调度然后切换执行

 

并行(Parallelism)

并行指线程同时进行

对于单个核心来说,一个时间端只能执行一个任务, 一定是并发,对于多核cup 是并行的

临界区

临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每一次,只能有一个线程使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。 

阻塞(Blocking)和非阻塞(Non-Blocking)

阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其它所有需要
这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。此时,如
果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。
非阻塞允许多个线程同时进入临界区

死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)

死锁是一个静态问题,如果发生死锁就会卡死,系统会把这个进程掉出去 ,抢占资源不释放就发生死锁,

活锁是动态的,会更加难查,

cs竞争,原子操作,一直失败,有可能会是这种问题

并发级别

阻塞

无障碍

无锁

无等待

阻塞

一个线程拿着资源之后另一个线程只能等待,

无障碍(Obstruction-Free)

无障碍是一种是最弱的非阻塞调度

自由出入临界值

无竞争时,有限步内完成操作

有竞争时,回滚数据

无锁

是无障碍的(条件)

保证有一个线程胜出

无等待

无锁的

要球所有的线程都能在有限步内完成

无饥饿的

无等待

读写操作

读的操作都是无等待的,因为读不会修改数据

写可能是会影响读,把要同时操作的数据拷贝一份,写操作拷贝的那一份,写的是副本,不影响读,这样都可以是无等待的,他们都不需要同步, 唯一需要的就是覆盖原始数据,

覆盖非常快的,

Amdahl定律(阿姆达尔定律)

定义了串行化后的加速比计算公式和理论上限

Gustafson定律(古斯塔夫森)

说明处理器个数,串行化比例和加速器的关系,

 

两个定律从两个角度说明,提高程序性能, 主要从 cpu 处理数,和并发线程

 

 

在java 中创建一个线程jvm 会把线程映射到window 进程上去,

 

调用start 方法才可以使用,进入runnable 状态,说这个线程是可以执行了,但是并不表示线程一定在cup执行,在jvm 层次上,我这个线程的所有工作所有的锁的申请以及相关工作到位了,但是系统本身很繁忙,cpu 没有时间, 还是不能执行,具体有没有执行取决于物理cpu 的状态,如果一个线程的所有工作做完了就会进入terminated

 

在线程执行的过程中有可能会申请一些锁,如果锁被别的线程占用, 申请不到锁这个线程会被挂起,如果一个线程调用waiting方法就会处于等待状态, 等待其他线程的通知, 如果被通知就会进入runnable 状态,然后继续执行,waiting 一种是无限等待一种是通过notifg方法通知线程脱离等待

Thread

开啊一个线程用start 方法, run方法是runable 接口的实现, 每开一个线程在java 中都要实现runable 接口中的run方法 start 方法调用的就是run方法

如果只调用run方法还是单线程的,执行run方法中的东西

Run 回到用target 然后还是runable 调用run 方法

在init 方法中要传入 runable run 方法,

  1. 重写run 方法
  2. 传递一个runable 接口的实例 ,调用thread 的一个构造方法,构造方法调用init方法

终止线程

Stop 方法可以停止线程,到那时strop 方法被启用了,stop 方法太暴力了,如果一个线程正在工作, 直接把线程杀死, 这个时候线程会释放所有的锁(monitor)有可能会导致多线程数据的不一致性

线程正在操作共享数据的时候,突然杀死,杀死hi后就会释放锁,如果后面有等待的线程就会导致,等待线程修改数据,这个时候数据会在前面线程的基础上修改,数据不一致这种行为很难发现,没有异常,只有发现数据错误离谱才能找

线程中断

public void Thread.interrupt()           // 中断线程

public boolean Thread.isInterrupted()    // 判断是否被中断

public static boolean Thread.interrupted() // 判断是否被中断,并清除当前中断状态

如果要中断线程, 会先给线程一个招呼,然后线程会自动的给自己中断点,然后到的时候就中断,

 

挂起(suspend) 继续执行(resume)线程

Suspend()不会释放锁

如果加锁发生在resume之前,则死锁发生

不推荐使用

如果一个线程被挂起,正在使用临界区资源,这样他不会释放锁,这样就会发生死锁,

没有办法确定 resume 发生在 suspend 之后,如果发生在suspend 之前,没有什么影响,这样线程就冻结了,其他线程拿不到锁,就死锁

Jvm 命令

Jps 查看所有进程

Jstack  调出指定的进程

 

notifyAll

 

唤醒在当前线程实例上的所有线程

任意的对象实例都有这些方法,因为方法定义在object 中,应用程序不用要notifyall 和notifyall 这里的方法是会被系统调用的, notifyall 是会被系统调用的不会如我们自己所愿,notifyall  是jvm层的代码是由c++ 实现的

 

守护进程

在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程

当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出

 

程序的目的就是执行我们非守护简称,辅助线程,支持程序比如  gc线程

 

 

线程优先级

 

 

线程优先级高的线程更有可能拿到资源执行

线程最高的优先级是10 在java 中,默认是5 ,最低的是1

线程基本同步操作

synchronized

– 指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。

– 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。

– 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。 、

synchronized   的底层代码是通过cpp 来实现的

1. 同步代码块

package com.Thread;

/**
 * @author ZZQ
 * @Title: java8_demo
 * @Package com.Thread
 * @date 2018/7/16 20:48
 */
public class Synchronizeddemo2 implements  Runnable{

    public static  int i = 0;




    public static synchronized  void staticmethod(){
        i++;
    }

    @Override
    public void run() {
        for (int j = 0 ; j < 100; j ++){
            staticmethod();
        }
    }




    public static void main(String[] args) throws Exception {
        Synchronizeddemo2 sy = new Synchronizeddemo2();
//        Thread t1 = new Thread(sy);
        Thread t2 = new Thread(sy);
//        t1.start();
        t2.start();
        //t1.join();
        t2.join();
        System.out.println(i);

    }

}

2. 同步静态方法

package com.Thread;

/**
 * @author ZZQ
 * @Title: java8_demo
 * @Package com.Thread
 * @date 2018/7/16 21:13
 */
public class Synchronizeddemo3 implements  Runnable {

    static  int i = 0 ;

    public static synchronized void newmethod(){
        i ++ ;
    }

    @Override
    public void run() {
        for (int i = 0 ; i<100; i ++){
            newmethod();
        }
    }


    public static void main(String[] args) throws  Exception {
        Thread t1 = new Thread(new Synchronizeddemo3());
        Thread t2 = new Thread(new Synchronizeddemo3());
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }


}

3. 同步方法

package com.Thread;

/**
 * @author ZZQ
 * @Title: java8_demo
 * @Package com.Thread
 * @date 2018/7/16 21:13
 */
public class Synchronizeddemo3 implements  Runnable {

    static  int i = 0 ;

    public static synchronized void newmethod(){
        i ++ ;
    }

    @Override
    public void run() {
        for (int i = 0 ; i<100; i ++){
            newmethod();
        }
    }


    public static void main(String[] args) throws  Exception {
        Thread t1 = new Thread(new Synchronizeddemo3());
        Thread t2 = new Thread(new Synchronizeddemo3());
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }


}

wait notify notifyall 方法

package com.Thread;

import java.time.Duration;
import java.time.Instant;

/**
 * @author ZZQ
 * @Title: java8_demo
 * @Package com.Thread
 * @date 2018/7/16 22:04
 */
public class ThreadWaitNotify {

    public  static ThreadWaitNotify threadWaitNotify = new ThreadWaitNotify();

    public static void main(String[] args) {
        new Thread(()->{
            synchronized (threadWaitNotify){
                try {
                    // jdk8 runable 是一个函数式接口
                    Instant in =  Instant.now();
                    threadWaitNotify.wait();
                    Instant out = Instant.now();
                    Duration between = Duration.between(in, out);
                    System.out.println(between.toMillis());
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();


        new Thread(()->{
            synchronized (threadWaitNotify){
                try{
                    threadWaitNotify.notify(); //唤醒在当前线程实例上的随机线程
                    System.out.println("notify执行完毕........");
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();



    }


}

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值