Java之 线程(二)

2021-09-07  本文已影响0人  五月笙

提问

Thread和Runnable的区别?
sleep和yield的区别?

线程同步

什么是线程同步?

如下代码

public class Data {
    private int count = 0;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

public class MyThreadRunnable implements Runnable {

    private Data data = new Data();

    @Override
    public void run() {
        int tmp = data.getCount();
        ++tmp;
        data.setCount(tmp);
        System.out.println(Thread.currentThread().getName() + "|" + data.getCount());
    }
}

执行方式为

MyThreadRunnable runnable = new MyThreadRunnable();
for (int i = 0; i < 5; i++) {
    Thread thread = new Thread(runnable);
    thread.start();
}

上面的打印结果为什么呢?

当然了这个只是一个简单的完全不耗时的操作,如果把执行代码块修改为

public class MyThreadRunnable implements Runnable {

    private Data data = new Data();

    @Override
    public void run() {
        int tmp = data.getCount();
        ++tmp;
        data.setCount(tmp);
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "|" + data.getCount());
    }
}

执行结果为

Thread-0|5
Thread-1|5
Thread-3|5
Thread-4|5
Thread-2|5

也就是说以上的代码执行有可能是无法预测的,需要增加一个同步操作来保证代码块的稳定。

synchronized

参考:synchronized-in-java

修改代码为

public class MyThreadRunnable implements Runnable {

    private Data data = new Data();

    @Override
    public synchronized void run() {
        int tmp = data.getCount();
        ++tmp;
        data.setCount(tmp);
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "|" + data.getCount());
    }
}

执行结果为:

Thread-0|1
Thread-4|2
Thread-3|3
Thread-2|4
Thread-1|5

wait,notify

实体数据

public class Data {
    private int count = 15;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

线程1

public class Thread1 extends Thread {

    private Data data;

    public Thread1(Data data) {
        super();
        this.data = data;
    }

    @Override
    public void run() {
        DataService service = new DataService();
        for (int i = 0; i < 100; i++) {
            service.add(data);
        }
    }
}

线程2

public class Thread2 extends Thread {

    private Data data;

    public Thread2(Data data) {
        super();
        this.data = data;
    }

    @Override
    public void run() {
        DataService service = new DataService();
        for (int i = 100; i > 0; i--) {
            service.del(data);
        }
    }
}

数据示例

public class DataService {

    private static final int MAX_COUNT = 10;
    private static final int MIN_COUNT = 1;

    public void add(Data data) {
        synchronized (data) {
            if (data.getCount() >= MAX_COUNT) {
                try {
                    System.out.println("count reach max");
                    data.wait();
                    System.out.println("count add wait finish");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return;
            }

            int count = data.getCount();
            ++count;
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data.setCount(count);
            System.out.println("current add count = " + data.getCount());
            data.notifyAll();
        }
    }

    public void del(Data data) {
        synchronized (data) {
            if (data.getCount() <= MIN_COUNT) {
                try {
                    System.out.println("count reach min");
                    data.wait();
                    System.out.println("count del wait finish");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return;
            }

            int count = data.getCount();
            count--;
            data.setCount(count);
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("current del count == " + data.getCount());
            data.notifyAll();
        }
    }
}

上面场景一般应用是什么?

上一篇 下一篇

猜你喜欢

热点阅读