展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

并发

  • 并发编程
计算机能运行多个程序,不同的程序在不同的单独的进程中运行
  • 串行与并行
串行是大家排队一个一个来,并行是大家一起上

  • 并发编程目的
摩尔定律:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。这一定律揭示了信息技术进步的速度。 让程序充分利用计算机资源 加快程序响应速度(耗时任务、web服务器) 简化异步事件的处理
  • 并发编程适用场景
任务会阻塞线程,导致之后的代码不能执行:比如一边从文件中读取,一边进行大量计算的情况 任务执行时间过长,可以划分为分工明确的子任务:比如分段下载 任务间断性执行:日志打印 任务本身需要协作执行:比如生产者消费者问题
  • 上下文切换
1、cpu为线程分配时间片,时间片非常短(毫秒级别),cpu不停的切换线程执行,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态,让我们感觉是多个程序同时运行的
2、上下文的频繁切换,会带来一定的性能开销

# 减少上下文切换的开销
1、无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据
2、CAS:Java的Atomic包使用CAS算法来更新数据,而不需要加锁。使用最少线程
3、使用最少线程:避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态
4、协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换
  • 死锁代码案例
public class DeadLockDemo {
    private static final Object HAIR_A = new Object();
    private static final Object HAIR_B = new Object();

    public static void main(String[] args) {
        new Thread(()->{
            synchronized (HAIR_A) {
                try {
                    Thread.sleep(50L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (HAIR_B) {
                    System.out.println("A成功的抓住B的头发");
                }
            }
        }).start();

        new Thread(()->{
            synchronized (HAIR_B) {
                synchronized (HAIR_A) {
                    System.out.println("B成功抓到A的头发");
                }
            }
        }).start();
    }
}
  • 查看是否发生死锁
# 打开cmd
# 输入jps
15472 Jps
14068 RemoteMavenServer36
18964 RemoteMavenServer36
12424
17276 DeadLockDemo

# 输入jstack 17276
Found one Java-level deadlock:
=============================
"Thread-0":
  waiting to lock monitor 0x000001f2d00c9f00 (object 0x000000071b79edb8, a java.lang.Object),
  which is held by "Thread-1"
"Thread-1":
  waiting to lock monitor 0x000001f2d00c9e00 (object 0x000000071b79eda8, a java.lang.Object),
  which is held by "Thread-0"

Java stack information for the threads listed above:
===================================================
"Thread-0":
        at com.xdclass.synopsis.DeadLockDemo.lambda$main$0(DeadLockDemo.java:19)

# 方式2
# cmd输入jconsole
# 选择不安全连接


  • 模拟线程不安全操作
# 创建10个线程,10个线程同时对1个变量操作,每次执行的结果不一致
public class UnSafeThread {

    private static int num = 0;

    private static CountDownLatch countDownLatch = new CountDownLatch(10);

    /**
     * 每次调用对num进行++操作
     */
    public static void  inCreate() {
        num++;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 100; j++) {
                    inCreate();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //每个线程执行完成之后,调用countDownLatch
                countDownLatch.countDown();
            }).start();
        }

        while (true) {
            if (countDownLatch.getCount() == 0) {
                System.out.println(num);
                break;
            }
        }

    }
}
posted @ 2022-05-08 17:51  DogLeftover  阅读(73)  评论(0编辑  收藏  举报