Java线程间的通信之锁与同步

Laughing
2021-06-06 / 0 评论 / 888 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年03月21日,已超过303天没有更新,若内容或图片失效,请留言反馈。

在Java中,锁的概念都是基于对象的,所以我们⼜经常称它为对象锁。线程和锁的关系,我们可以⽤婚姻关系来理解。⼀个锁同⼀时间只能被⼀个线程持有。也就是说,⼀个锁如果和⼀个线程“结婚”(持有),那其他线程如果需要得到这个锁,就得等这个线程和这个锁“离婚”(释放)。
在我们的线程之间,有⼀个同步的概念。什么是同步呢,假如我们现在有2位正在抄暑假作业答案的同学:线程A和线程B。当他们正在抄的时候,⽼师突然来修改了⼀些答案,可能A和B最后写出的暑假作业就不⼀样。我们为了A,B能写出2本相同的暑假作业,我们就需要让⽼师先修改答案,然后A,B同学再抄。或者A,B同学先抄完,⽼师再修改答案。这就是线程A,线程B的线程同步。
可以以解释为:线程同步是线程之间按照⼀定的顺序执⾏。
为了达到线程同步,我们可以使⽤锁来实现它。
我们先来看看⼀个⽆锁的程序:

package com.company;

import java.util.stream.IntStream;

public class NoneLock {

    static class ThreadA implements Runnable {

        @Override
        public void run() {
            IntStream.range(1, 100).forEach(i -> {
                System.out.println("threadA:" + i);
            });
        }
    }

    static class ThreadB implements Runnable {

        @Override
        public void run() {
            IntStream.range(1, 100).forEach(i -> {
                System.out.println("threadB:" + i);
            });
        }
    }

    public static void main(String[] args) {
        new Thread(new ThreadA()).start();
        new Thread(new ThreadB()).start();
    }

}

某次的运行结果
那我现在有⼀个需求,我想等A先执⾏完之后,再由B去执⾏,怎么办呢?最简单的⽅式就是使⽤⼀个“对象锁”:

package com.company;

import java.util.stream.IntStream;

public class ObjectLock {

    private static final Object lock = new Object();

    static class ThreadA implements Runnable {

        @Override
        public void run() {
            synchronized (lock) {
                IntStream.range(1, 100).forEach(i -> {
                    System.out.println("threadA:" + i);
                });
            }
        }
    }

    static class ThreadB implements Runnable {

        @Override
        public void run() {
            synchronized (lock) {
                IntStream.range(1, 100).forEach(i -> {
                    System.out.println("threadB:" + i);
                });
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new Thread(new ThreadA()).start();
        Thread.sleep(10);
        new Thread(new ThreadB()).start();
    }

}
0

评论 (0)

取消
  1. 头像
    wutou
    Windows 7 · MicroSoft Edge

    不知道能不能用?

    回复
  2. 头像
    Windows 10 · QQ Browser

    呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃

    回复