1、线程间的通信
需求:在一个线程执行增值后,两个线程进行读取,等待两个线程都读取完成之后再次进行增值。
采用了三种方式解决
方式一:使用传参确定当前线程和本线程执行完成后开启的下一个线程
方式二:使用Set集收集读取过的线程,所有读取功能线程读取完成,开启增值线程
方式三:使用Map集收集读取过的线程,所有读取功能线程读取完成,开启增值线程
代码示例:
Calculation 类中的主要方法
public synchronized void set(int n, int f) {
try {
Thread.sleep(200);
while (flag != n) {
wait();
}
int nn = (int) (Math.random() * 10);
System.out.println(Thread.currentThread().getName() + "将" + i + "加" + nn + "计算为:" + (i + nn));
i = i + nn;
flag = f;
notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void get(int n, int f) {
try {
Thread.sleep(200);
while (flag != n) {
wait();
}
System.out.println(Thread.currentThread().getName() + "检查为:" + i);
flag = f;
notifyAll();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
/**
* 使用Set集将前来操作的线程进行储存, 操作完的线程不能进行操作 所有查询数据的线程操作完成后,开启计算线程
*/
public synchronized void getUsedSet() {
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
int sum = set.size();
if (sum != getSize) {
while (flag != 1) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
set.add(Thread.currentThread());
if (set.size() > sum) {
System.out.println(Thread.currentThread().getName() + "检查为:" + i);
if (set.size() == getSize) {
flag = 0;
set.clear();
notifyAll();
}
}
}
}
/**
* 使用Map将前来操作的线程进行储存并给予初始值false, 操作完的线程给予true值,未进行操作的线程为false值
* 所有查询数据的线程操作完成后,开启计算线程
*/
public synchronized void getUsedMap() {
try {
Thread.sleep(200);
while (flag != 1) {
wait();
}
if (!m.containsKey(Thread.currentThread())) {
m.put(Thread.currentThread(), false);
}
if (m.containsKey(Thread.currentThread())) {
if (!m.get(Thread.currentThread())) {
m.put(Thread.currentThread(), true);
System.out.println(Thread.currentThread().getName() + "检查为:" + i);
}
}
if (m.keySet().size() == getSize) {
flag = 0;
m.clear();
}
notifyAll();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
ThreadDemo1 线程(增值)中run方法
while(true) {
//使用传参的方式
caluction.set(0,1);
//使用Set或Map收集查询线程的方式
// caluction.set();
}
ThreadDemo2 类(读取线程1)中run方法
while(true) {
//使用传参的方式
caluction.get(1,2);
//使用Set收集查询线程的方式
// caluction.getUsedSet();
//使用Map收集查询线程的方式
// caluction.getUsedMap();
}
ThreadDemo3 类(读取线程2)中run方法
while(true) {
//使用传参的方式
caluction.get(2,0);
//使用Set收集查询线程的方式
// caluction.getUsedSet();
//使用Map收集查询线程的方式
// caluction.getUsedMap();
}
MainEnter 类(运行类)
public class MainEnter {
public static void main(String[] args) {
Calculation caluction = new Calculation();
caluction.getSize = 2;
Runnable r1 = new ThreadDemo1(caluction);
Runnable r2 = new ThreadDemo2(caluction);
Runnable r3 = new ThreadDemo3(caluction);
Thread t1 = new Thread(r1,"小明");
Thread t2 = new Thread(r2,"他爸");
Thread t3 = new Thread(r3,"他妈");
t1.start();
t2.start();
t3.start();
}
}