java

java-多线程同步

多线程 - 同步

同步

可以避免线程干扰和内存一致性错误 synchronized 关键字

经典卖票问题

假设我们开启3个窗口进行卖票

class Test implements Runnable {
    private int tick = 100;
    @Override
    public void run() {
        while (true) {
            if (tick > 0) {
                System.out.println(Thread.currentThread().getName() + "当前票" + tick);
                tick--;
            } else {
                break;
            }
        }
    }
}

public class TestSync {
    public static void main(String[] args) {
        Test test = new Test();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        Thread t3 = new Thread(test);
        t1.start();
        t2.start();
        t3.start();
    }
}

我们创建了一个Runnable, 开启两个线程执行Runnable, 打印结果:

Thread-0当前票100
Thread-2当前票100
Thread-1当前票100
Thread-2当前票98
Thread-0当前票99
Thread-0当前票95
Thread-2当前票96
Thread-1当前票97
...

打印出的结果, 并没有达到我们的效果, 并且出现了重复数据

思考:为什么重复?

开启两个线程, 对一个共享数据进行操作,一个线程没执行完, 另外一个线程也跟进来, 然后读取的共享数据count,就相同, 这里我们就使用 synchronized 关键字:

一、synchronized 代码块中的代码是同步执行,A线程执行完才轮到B线程;不在synchronized代码块中则是异步执行。

二、synchronized(this) 和 synchronized 方法一样,锁定的是当前对象。也就是说:当多个线程同时访问 同一个 object对象的synchronized(this) 方法时,该object 对象中其他synchronized(this) 或者 synchronized 方法都会被阻塞,因为它们使用的是同一个对象锁。

1.同步代码块解决:



class Test implements Runnable{
    private int tick =100;
    @Override
    public void run() {
        while (true) {
            synchronized (this){
                if (tick > 0) {
                    System.out.println(Thread.currentThread().getName()+"当前票"+tick);
                    tick -- ;
                } else {
                    break;
                }
            }

        }
    }
}

public class TestSync {
    public static void main(String[] args) {
        Test test = new Test();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        Thread t3 = new Thread(test);
        t1.start();
        t2.start();
        t3.start();
    }
}

2.同步方法解决


class Test implements Runnable{
    private int tick =100;
    @Override
    public void run() {
        while (true) {
            reduce();
        }
    }
    synchronized void reduce(){
        if (tick > 0) {
            System.out.println(Thread.currentThread().getName()+"当前票"+tick);
            tick -- ;
        }
    }
}

public class TestSync {
    public static void main(String[] args) {
        Test test = new Test();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        Thread t3 = new Thread(test);
        t1.start();
        t2.start();
        t3.start();
    }
}

打印:

Thread-0当前票100
Thread-0当前票99
Thread-0当前票98
Thread-0当前票97
Thread-0当前票96
Thread-0当前票95
Thread-0当前票94
Thread-0当前票93

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!
文章若有侵权请立即与我联系, 我将及时处理
微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

支付宝扫一扫,向我赞赏

回复

This is just a placeholder img.
Title - Artist
0:00