java中的并发编程

1、上下文切换

即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现 这个机制。这个时间片特别短,一般是几十毫秒,所以会让我们觉得好多任务同时进行。 CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个 任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这 个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。,例如:

当我们在读一本英文的技术书时,发现某个单词不认识,于是 便打开中英文字典,但是在放下英文技术书之前,大脑必须先记住这本书读到了多少页的第 多少行,等查完单词之后,能够继续读这本书

2、多线程一定快吗

我们用一段代码来查看多线程并发是否就一定比串行快

public class ConcurrencyTest {
    private static final long count = 1000000L;

    public static void main(String[] args) throws Exception{
        concurrentcy();;  //并发执行程序
        serial();       //串行方法
    }
    private static void concurrentcy() throws Exception {
        long start = System.currentTimeMillis();  //获取当前系统时间
        Thread thread = new Thread(() -> {
            int a = 0;
            for (long i = 0; i < count; i++) {
                a += 5;
            }
        });
        thread.start();
        int b = 0;
        for (long i = 0; i < count; i++) {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        thread.join();
        System.out.println(String.format("concurrecy: %dms, b=%d", time, b));
    }

    private static void serial() {
        long start = System.currentTimeMillis();
        int a = 0;
        for (long i = 0; i < count; i++) {
            a += 5;
        }
        int b = 0;
        for (long i = 0; i < count; i++) {
            b --;
        }
        long time = System.currentTimeMillis() - start;
        System.out.println(String.format("serial: %dms, b=%d", time, b));
    }
}

在我们对count值更改多次后,得出结论如下:

显然,当任务次数在低于1百万时,串行的效率是比并发要高的,这是什么原因呢?因为并发线程有创建和上下文切换的开 销。

减少上下文切换的方法:

3、死锁DeadLock

死锁是指多个进程在运行过程中因争夺资源而造成的一种僵局,若无外力帮助,则它们都无法继续向前推进,直到程序崩溃为止。我们举一个例子:

  public class DeadLockTest {
      public static Object A = new Object();
      public static Object B = new Object();
  
      public static void main(String[] args) {
          new Thread(()->{
              synchronized (A){
                  System.out.println(Thread.currentThread().getName()+"获取了资源A的锁");
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
  
                  synchronized (B){
                      System.out.println(Thread.currentThread().getName()+"获取了资源B的锁");
                  }
              }
          }).start();
  
          new Thread(()->{
              synchronized (B){
                  System.out.println(Thread.currentThread().getName()+"获取了资源A的锁");
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  synchronized (A){
                      System.out.println(Thread.currentThread().getName()+"获取了资源B的锁");
                  }
              }
          }).start();
      }
  }
  ```

- 该类中,两个线程会发生死锁,因为程序启动时,两个线程几乎同时对A与B上锁,然后又几乎同时开始申请B与A资源,此时便发生了死锁,此时想要解决的话只能从外部强行把发生死锁的进程进行终止,windows的方法如下

首先,使用jps查看java所运行的线程信息,如下

我么可以看到共有4个,然后使用jstack查看线程信息

  • 可以发现,Thread-0与Thread-1是处于locked状态,也就是发生了死锁,此时再执行taskkill /F /PID来将死锁的线程强行终止

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值