美文网首页
Java之 线程(二)

Java之 线程(二)

作者: 五月笙 | 来源:发表于2021-09-07 10:30 被阅读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

  • wait()
    Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
  • void wait(long timeout)
    Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
  • void wait(long timeout, int nanos)
    Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
  • void notify()
    Wakes up a single thread that is waiting on this object's monitor.
  • void notifyAll()
    Wakes up all threads that are waiting on this object's monitor.

实体数据

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();
        }
    }
}

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

相关文章

  • JAVA线程面试题书目录

    JAVA线程面试题之1) 什么是线程? JAVA线程面试题之2) 线程和进程有什么区别? JAVA线程面试题之3)...

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • Java之 线程(二)

    提问 Thread和Runnable的区别?sleep和yield的区别? 线程同步 什么是线程同步? 如下代码 ...

  • 带你搞懂Java多线程(四)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三) 什么是线程间的协作 线程之间...

  • Java学习笔记之线程

    Java学习笔记之线程 线程的定义 线程有两种定义方法:一是继承Thread类;二是实现Runabble接口。 继...

  • 知识梳理目录

    Java基础 Java线程池 AQS之独占锁 AQS之Condition AQS之Condition AQS之同步...

  • 带你搞懂Java多线程(三)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二) 什么是线程间的共享 Java支持多个线程同时访问一个对象...

  • java线程入门基础(二)

    java线程入门基础(二) 一、认识Java里的线程 1.1 Java里的程序天生就是多线程的 一个Java程序从...

  • 【学习笔记】java线程池

    深入理解Java之线程池

网友评论

      本文标题:Java之 线程(二)

      本文链接:https://www.haomeiwen.com/subject/nrvmnktx.html