提问
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
修改代码为
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();
}
}
}
上面场景一般应用是什么?