一道多线程练习题

时间:2023-02-23 15:11:16
俩.txt文件,内容分别是
data1.txt                      data2.txt
Name,value1,value2,value3      Name,value1,value2,value3
N1,2,5,3                       N2,1,3,2
N1,3,1,2                       N3,1,3,6
N3,2,2,2                       N2,1,3,3
N2,1,1,1                       N1,2,4,1

要求是用三个线程处理,读取上述俩文件内容,统计数据,写出data3.txt 内容处理统计出的数据外,附加value4,=value1/(value2+value3);

我的思路是在主类设两个变量,其中一个同步的临时变量,读线程读取一行数据到临时变量中,统计线程把临时变量数据统计到目标变量中,这里的两个线程交互执行没有弄好,
求解~~~~

14 个解决方案

#1


关键就是交互执行的功能没做出来

#2


都上班没时间吗

#3


2个流读文件 1个流写 要什么线程 

#4


引用 3 楼 kiss601459202 的回复:
2个流读文件 1个流写 要什么线程

同意这个观点, 一个读完接着下一个, 再一个读完就写, 顺序执行, 你搞线程通信还不是要把两个线程阻塞在那里嘛

#5


引用楼主 kjimmieb 的回复:
俩.txt文件,内容分别是
data1.txt                      data2.txt
Name,value1,value2,value3      Name,value1,value2,value3
N1,2,5,3                       N2,1,3,2
N1,3,1,2                       N3,1,3,6
N3,……


自己看看 CyclicBarrier

#6


CountDownLatch

这个就可以了

#7


需求都描述不明白,还整多线程!
对两个文件的内容进行处理,怎么处理?name相同的进行合并?加还是减?
生成第三个文件,形式是什么样的?总共几列?每一列的值是怎么来的?

#8


引用 6 楼 zhao251021539 的回复:
CountDownLatch

这个就可以了


+1

#9


好吧,是我没说清楚, 需求就是 统计data1.txt 和data2.txt 的数据,Name相同的相加,value4=(value1+value2)/value3
最后 data3.txt 内容就是
Name,value1,value2,value3,value4
N1,*,*,*,*
N2,*,*,*,*
N3,*,*,*,*

我想的就是 读线程每读一行数据到临时变量中,统计线程就把这一行数据统计到一个变量中,
     类似 统计线程监控 临时变量,有一条统计一条,

#10


起2个线程分别去读取文件至全局变量中,同时加入value4.
第3个线程等前面2个线程读取完成后把data写进文件。

#11


引用 10 楼 zyc13701469860 的回复:
起2个线程分别去读取文件至全局变量中,同时加入value4.
第3个线程等前面2个线程读取完成后把data写进文件。

我就是这样想法的,但代码实现的时候总出现问题,能写个大致的代码吗,谢了

#12



package test.thread;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author xujsh
 * @created 2011-8-26下午13:45:04
 */
class NameValues implements Comparable<NameValues> {
private String name;
private int value1;
private int value2;
private int value3;

public NameValues(String name, int value1, int value2, int value3) {
this.name = name;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}

public NameValues(String nameValues) {
String arr[] = nameValues.split(",");
this.name = arr[0];
this.value1 = Integer.parseInt(arr[1]);
this.value2 = Integer.parseInt(arr[2]);
this.value3 = Integer.parseInt(arr[3]);
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof NameValues)) {
return false;
}
NameValues other = (NameValues) obj;
return (this.name.equals(other.name)) && (this.value1 == other.value1)
&& (this.value2 == other.value2)
&& (this.value3 == other.value3);
}

@Override
public int hashCode() {
int result = 13;
result += name.hashCode() * 31;
result += value1 * 31;
result += value2 * 31;
result += value3 * 31;
return result;
}
@Override
public int compareTo(NameValues other) {
return this.name.compareTo(other.name);
}
//对两个NameValues进行相加
public NameValues add(NameValues other) {
if (this.name.equals(other.name)) {
return new NameValues(this.name, this.value1 + other.value1,
this.value2 + other.value2, this.value3 + other.value3);
} else {
return this;
}
}
@Override
public String toString() {
return "[" + name + "," + value1 + "," + value2 + "," + value3 + "]";
}

public String getName() {
return name;
}

public int getValue1() {
return value1;
}

public int getValue2() {
return value2;
}

public int getValue3() {
return value3;
}

public int getValue4() {
return (value1 + value2) / value3;
}

}
class ReadThread extends Thread {
private String filename;
private BlockingQueue<NameValues> queue;
private CountDownLatch latch;

public ReadThread(String filename, BlockingQueue<NameValues> queue,
CountDownLatch latch) {
this.filename = filename;
this.queue = queue;
this.latch = latch;
}

public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(filename)));
String line = "";
while ((line = br.readLine()) != null) {
try {
Thread.sleep(10);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ ":is putting " + new NameValues(line));
queue.put(new NameValues(line));
}
br.close();
System.out.println(Thread.currentThread().getName() + ":is over!");
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}

class WriteThread extends Thread {
private String filename;
private BlockingQueue<NameValues> queue;
private CountDownLatch latch;
private OutputStream out;

public WriteThread(String filename, BlockingQueue<NameValues> queue,
CountDownLatch latch) {
this.filename = filename;
this.queue = queue;
this.latch = latch;
}

public void run() {
try {
//等待读文件结束
latch.await();
System.out.println("begin to write...");
if (out == null)out = new FileOutputStream(filename);
NameValues[] values = queue.toArray(new NameValues[0]);
//生成计算结果
for (int i = 0; i < values.length; i++) {
if (values[i] == null)continue;
for (int j = i + 1; j < values.length; j++) {
if (values[j] == null)continue;
if (values[i].add(values[j]) != values[i]) {
values[i] = values[i].add(values[j]);
values[j] = null;
}
}
}
//对结果进行排序
Set<NameValues> resultSet = new TreeSet<NameValues>();
for (int i = 0; i < values.length; i++) {
if (values[i] == null)continue;
resultSet.add(values[i]);
}
//输出结果
for (Iterator<NameValues> it = resultSet.iterator(); it.hasNext();) {
NameValues value = it.next();
StringBuilder sb = new StringBuilder();
sb.append(value.getName()).append(",");
sb.append(value.getValue1()).append(",");
sb.append(value.getValue2()).append(",");
sb.append(value.getValue3()).append(",");
sb.append(value.getValue4()).append("\r\n");
out.write(sb.toString().getBytes());
}
out.close();
System.out.println(Thread.currentThread().getName() + ":is over!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class TheadTest {
public static void main(String[] args) {
//阻塞队列,允许两个线程同时往里面写数据
BlockingQueue<NameValues> queue = new LinkedBlockingQueue<NameValues>();
//两个读线程读取数据完毕以后,可以进行写文件操作
CountDownLatch latch = new CountDownLatch(2);
//读文件的线程池
ExecutorService readers = Executors.newFixedThreadPool(2);
//写文件的线程池
ExecutorService writers = Executors.newFixedThreadPool(1);
readers.execute(new ReadThread("1.txt", queue, latch));
readers.execute(new ReadThread("2.txt", queue, latch));
writers.execute(new WriteThread("3.txt", queue, latch));
//关闭线程池
readers.shutdown();
writers.shutdown();
}
}

#13


引用 12 楼 goldenfish1919 的回复:
Java code

package test.thread;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
……

写的这么详细呀,先谢了哈,我仔细看看,有些类都没有使过的还

#14


引用 12 楼 goldenfish1919 的回复:
Java code


package test.thread;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream……

运行了一下代码,也放了两个txt到相应的bin目录下了,怎么还是会报找不到文件的错误啊

#1


关键就是交互执行的功能没做出来

#2


都上班没时间吗

#3


2个流读文件 1个流写 要什么线程 

#4


引用 3 楼 kiss601459202 的回复:
2个流读文件 1个流写 要什么线程

同意这个观点, 一个读完接着下一个, 再一个读完就写, 顺序执行, 你搞线程通信还不是要把两个线程阻塞在那里嘛

#5


引用楼主 kjimmieb 的回复:
俩.txt文件,内容分别是
data1.txt                      data2.txt
Name,value1,value2,value3      Name,value1,value2,value3
N1,2,5,3                       N2,1,3,2
N1,3,1,2                       N3,1,3,6
N3,……


自己看看 CyclicBarrier

#6


CountDownLatch

这个就可以了

#7


需求都描述不明白,还整多线程!
对两个文件的内容进行处理,怎么处理?name相同的进行合并?加还是减?
生成第三个文件,形式是什么样的?总共几列?每一列的值是怎么来的?

#8


引用 6 楼 zhao251021539 的回复:
CountDownLatch

这个就可以了


+1

#9


好吧,是我没说清楚, 需求就是 统计data1.txt 和data2.txt 的数据,Name相同的相加,value4=(value1+value2)/value3
最后 data3.txt 内容就是
Name,value1,value2,value3,value4
N1,*,*,*,*
N2,*,*,*,*
N3,*,*,*,*

我想的就是 读线程每读一行数据到临时变量中,统计线程就把这一行数据统计到一个变量中,
     类似 统计线程监控 临时变量,有一条统计一条,

#10


起2个线程分别去读取文件至全局变量中,同时加入value4.
第3个线程等前面2个线程读取完成后把data写进文件。

#11


引用 10 楼 zyc13701469860 的回复:
起2个线程分别去读取文件至全局变量中,同时加入value4.
第3个线程等前面2个线程读取完成后把data写进文件。

我就是这样想法的,但代码实现的时候总出现问题,能写个大致的代码吗,谢了

#12



package test.thread;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author xujsh
 * @created 2011-8-26下午13:45:04
 */
class NameValues implements Comparable<NameValues> {
private String name;
private int value1;
private int value2;
private int value3;

public NameValues(String name, int value1, int value2, int value3) {
this.name = name;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}

public NameValues(String nameValues) {
String arr[] = nameValues.split(",");
this.name = arr[0];
this.value1 = Integer.parseInt(arr[1]);
this.value2 = Integer.parseInt(arr[2]);
this.value3 = Integer.parseInt(arr[3]);
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof NameValues)) {
return false;
}
NameValues other = (NameValues) obj;
return (this.name.equals(other.name)) && (this.value1 == other.value1)
&& (this.value2 == other.value2)
&& (this.value3 == other.value3);
}

@Override
public int hashCode() {
int result = 13;
result += name.hashCode() * 31;
result += value1 * 31;
result += value2 * 31;
result += value3 * 31;
return result;
}
@Override
public int compareTo(NameValues other) {
return this.name.compareTo(other.name);
}
//对两个NameValues进行相加
public NameValues add(NameValues other) {
if (this.name.equals(other.name)) {
return new NameValues(this.name, this.value1 + other.value1,
this.value2 + other.value2, this.value3 + other.value3);
} else {
return this;
}
}
@Override
public String toString() {
return "[" + name + "," + value1 + "," + value2 + "," + value3 + "]";
}

public String getName() {
return name;
}

public int getValue1() {
return value1;
}

public int getValue2() {
return value2;
}

public int getValue3() {
return value3;
}

public int getValue4() {
return (value1 + value2) / value3;
}

}
class ReadThread extends Thread {
private String filename;
private BlockingQueue<NameValues> queue;
private CountDownLatch latch;

public ReadThread(String filename, BlockingQueue<NameValues> queue,
CountDownLatch latch) {
this.filename = filename;
this.queue = queue;
this.latch = latch;
}

public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(filename)));
String line = "";
while ((line = br.readLine()) != null) {
try {
Thread.sleep(10);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ ":is putting " + new NameValues(line));
queue.put(new NameValues(line));
}
br.close();
System.out.println(Thread.currentThread().getName() + ":is over!");
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}

class WriteThread extends Thread {
private String filename;
private BlockingQueue<NameValues> queue;
private CountDownLatch latch;
private OutputStream out;

public WriteThread(String filename, BlockingQueue<NameValues> queue,
CountDownLatch latch) {
this.filename = filename;
this.queue = queue;
this.latch = latch;
}

public void run() {
try {
//等待读文件结束
latch.await();
System.out.println("begin to write...");
if (out == null)out = new FileOutputStream(filename);
NameValues[] values = queue.toArray(new NameValues[0]);
//生成计算结果
for (int i = 0; i < values.length; i++) {
if (values[i] == null)continue;
for (int j = i + 1; j < values.length; j++) {
if (values[j] == null)continue;
if (values[i].add(values[j]) != values[i]) {
values[i] = values[i].add(values[j]);
values[j] = null;
}
}
}
//对结果进行排序
Set<NameValues> resultSet = new TreeSet<NameValues>();
for (int i = 0; i < values.length; i++) {
if (values[i] == null)continue;
resultSet.add(values[i]);
}
//输出结果
for (Iterator<NameValues> it = resultSet.iterator(); it.hasNext();) {
NameValues value = it.next();
StringBuilder sb = new StringBuilder();
sb.append(value.getName()).append(",");
sb.append(value.getValue1()).append(",");
sb.append(value.getValue2()).append(",");
sb.append(value.getValue3()).append(",");
sb.append(value.getValue4()).append("\r\n");
out.write(sb.toString().getBytes());
}
out.close();
System.out.println(Thread.currentThread().getName() + ":is over!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class TheadTest {
public static void main(String[] args) {
//阻塞队列,允许两个线程同时往里面写数据
BlockingQueue<NameValues> queue = new LinkedBlockingQueue<NameValues>();
//两个读线程读取数据完毕以后,可以进行写文件操作
CountDownLatch latch = new CountDownLatch(2);
//读文件的线程池
ExecutorService readers = Executors.newFixedThreadPool(2);
//写文件的线程池
ExecutorService writers = Executors.newFixedThreadPool(1);
readers.execute(new ReadThread("1.txt", queue, latch));
readers.execute(new ReadThread("2.txt", queue, latch));
writers.execute(new WriteThread("3.txt", queue, latch));
//关闭线程池
readers.shutdown();
writers.shutdown();
}
}

#13


引用 12 楼 goldenfish1919 的回复:
Java code

package test.thread;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
……

写的这么详细呀,先谢了哈,我仔细看看,有些类都没有使过的还

#14


引用 12 楼 goldenfish1919 的回复:
Java code


package test.thread;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream……

运行了一下代码,也放了两个txt到相应的bin目录下了,怎么还是会报找不到文件的错误啊