如何在两个线程之间共享数据

152 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

方法一:将数据抽象成一个类,并将对这个数据的操作封装在类的方法中。(这种方式只需要在方法上加synchronized关键字即可做到数据的同步。

1.将数据抽象成MyData类,并将数据的操作作为类的方法(方法上加synchronized关键字)。

public class MyData {

    private int j = 0;

    public synchronized void add(){
        j++;
        System.out.println("线程"+Thread.currentThread().getName()+"j为:"+j);
    }

    public synchronized void dec(){
        j--;
        System.out.println("线程"+Thread.currentThread().getName()+"j为:"+j);
    }

    public int getData(){
        return j;
    }
}

2.线程使用该类的对象并调用类的方法对数据进行操作

public class AddRunnable extends Thread{
    MyData data;

    public AddRunnable(MyData data) {
        this.data = data;
    }

    @Override
    public void run() {
        data.add();
    }
}
public class DecRunnable extends Thread {
    MyData data;

    public DecRunnable(MyData data) {
        this.data = data;
    }

    @Override
    public void run() {
        data.dec();
    }
}

3.测试

public class Demo {

    public static void main(String[] args) {
        MyData data = new MyData();

        for (int i = 0; i < 2; i++) {
            new AddRunnable(data).start();
            new DecRunnable(data).start();
        }
    }
}

==================
运行结果
==================
线程Thread-0j为:1
线程Thread-1j为:0
线程Thread-2j为:1
线程Thread-3j为:0

1)对数据 j 操作的方法需要使用synchronized修饰,以保障在多个并发线程访问对象 j 时执行加锁操作,以便同时只有一个线程有权利访问,可以保障数据的一致性。
2)synchronized修饰的是普通方法,作用范围一个对象,前面的线程需要保障数据操作的原子性和一致性,就必须传入同一个对象。

方法二:将Runnable对象作为一个类的内部类,将共享数据作为这个类的成员变量。

1.共享数据:

public class MyData {

    private int j = 0;

    public synchronized void add(){
        j++;
        System.out.println("线程"+Thread.currentThread().getName()+"j为:"+j);
    }

    public synchronized void dec(){
        j--;
        System.out.println("线程"+Thread.currentThread().getName()+"j为:"+j);
    }

    public int getData(){
        return j;
    }
}

2.将Runnable对象作为一个类的内部类,将共享数据作为这个类的成员变量,每个线程对共享数据的操作方法都被封装在该类的外部类中,以便实现对数据的各个操作的同步和互斥,作为内部类的各个Runnable对象调用外部类的这些方法。

public class Demo02 {
    public static void main(String[] args) {
        final MyData data = new MyData();
        for(int i=0;i<2;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    data.add();
                }
            }).start();
            new Thread(new Runnable(){
                @Override
                public void run() {
                    data.dec();
                }
            }).start();
        }
    }
}

==================
运行结果
==================
线程Thread-0j为:1
线程Thread-1j为:0
线程Thread-2j为:1
线程Thread-3j为:0