题目:
-------------------------------------------------------------------------------------------------------------------------------------------------
代码:
import java.io.*;
import java.util.*;
class Storge
{
int sum; //表示需要运送的商品总数
int n; //格子可放商品总数
int inSet = 0; //表示在格子里的商品数
int condition = 1; //表示目前的进度,数字按照流程排序,1为第一类工人在工作,2为管理员在工作,3为第二类工人在工作,4为所有工作结束
boolean endAll = false; //用来判断商品搬运工作是否全部完成
HashSet<String> set = new HashSet<String>(); //仓库,格子上限为k,故最多存放k件商品
ArrayList<String> list=new ArrayList<String>(); //用来保存所有商品
BufferedWriter bw = null;
BufferedReader br = null;
StringBuffer str = null;
void init(int s, int n)
{
this.n = n;
sum = s;
for (int i = 1; i <= sum; i++)
list.add("商品" + i);
}
public synchronized void job1() //第一类工人的工作
{
Thread thread = Thread.currentThread();
while (condition != 1)
{
try
{
wait();
}
catch(InterruptedException e) {}
}
Iterator it = list.iterator();
if (it.hasNext())
{
String temp = (String)it.next();
set.add(temp);
System.out.println(thread.getName() + ",将" + temp + "搬进仓库");
it.remove();
inSet++;
}
else endAll = true;
if (n == inSet || endAll)
{
condition = 2;
System.out.println("******搬完一趟休息下******");
}
notifyAll();
}
public synchronized void job2() //管理员的工作
{
while (condition != 2)
{
try
{
wait();
}
catch(InterruptedException e) {}
}
condition = 3;
//为了避免写入时被覆盖,每次都要把文件里的内容先读到 StringBuffer,再用append函数将集合里的元素加入进来
StringBuffer str = new StringBuffer("");
String temp = null;
try
{
br = new BufferedReader(new FileReader("D:\\goods.txt"));
while ((temp = br.readLine()) != null)
{ temp = temp + "\r\n";
str.append(temp);
}
br.close();
}
catch(EOFException e){}
catch(IOException e){}
//文件第一次读取时是不存在的,因此要捕捉这个异常。不能和写放在一起
try
{
bw = new BufferedWriter(new FileWriter("D:\\goods.txt"));
bw.write(str.toString());
Iterator it = set.iterator();
while (it.hasNext())
{
temp = (String)it.next();
bw.write(temp);
bw.newLine();
}
bw.close();
}
catch(EOFException e){}
catch(IOException e){}
notifyAll();
}
public synchronized void job3()//第二类工人的工作
{
Thread thread = Thread.currentThread();
while (condition != 3)
{
try
{
wait();
}
catch(InterruptedException e) {}
}
Iterator it = set.iterator();
if(it.hasNext())
{
String s=(String)it.next();
System.out.println(thread.getName()+",从仓库中搬走"+s);
it.remove();
inSet--;
}
if (inSet == 0) //格子中的搬完后,第二类工人就可以休息了
{
System.out.println("******搬完一趟休息下******");
condition = 1; //接着是第一类工人工作
if (endAll) showInfo();
}
notifyAll();
}
public synchronized void showInfo() //在搬运完成后,读取文件,并输出相关信息,停止所有线程
{
System.out.println("工作结束了");
System.out.println("------仓库中的商品为------");
try
{
br = new BufferedReader(new FileReader("D:\\goods.txt"));
String temp = null;
while ((temp = br.readLine()) != null)
{
System.out.println(temp);
}
}
catch(Exception e) {e.printStackTrace();} //用于处理文件读到末尾时,遇到EOF时,抛出的异常,以及IOException
System.exit(0);
}
}
class Worker1 implements Runnable //第一类工人
{
Storge s = null;
Worker1(Storge s)
{
this.s = s;
}
public void run()
{
while(true)
{
try
{
s.job1();
Thread.sleep((int)Math.random() * 500);
}
catch(InterruptedException e) {}
}
}
}
class Worker2 implements Runnable //第二类工人
{
Storge s = null;
Worker2(Storge s)
{
this.s = s;
}
public void run()
{
while(true)
{
try
{
s.job3();
Thread.sleep((int)Math.random() * 500);
}
catch(InterruptedException e) {}
}
}
}
class Manager implements Runnable //管理员
{
Storge s = null;
Manager(Storge s)
{
this.s = s;
}
public void run()
{
while(true)
{
try
{
s.job2();
Thread.sleep((int)Math.random() * 500);
}
catch(InterruptedException e) {}
}
}
}
public class test
{
public static void main(String[] args)
{
solve();
}
public static void solve()
{
int n, sum;
Scanner sc = new Scanner(System.in);
System.out.println("请输入仓库格子数 n:");
System.out.print("n = ");
n = sc.nextInt();
System.out.println();
System.out.println("请输入商品总数 sum:");
System.out.print("sum = ");
sum = sc.nextInt();
System.out.println();
Storge s = new Storge();
s.init(sum, n);
Thread threads[] = new Thread[5];
for (int i = 0; i < 2; i++)
{
threads[i] = new Thread(new Worker1(s));
threads[i].setName("我是第一类的第" + (i+1) + "个工人");
}
for (int i = 2; i < 4; i++)
{
threads[i] = new Thread(new Worker2(s));
threads[i].setName("我是第二类的第" + (i-1) + "个工人");
}
threads[4] = new Thread(new Manager(s));
for (int i = 0; i < 5; i++)
threads[i].start();
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------
实验报告其他部分:
五、心得体会(碰到的问题及解决方案)
体会:
做这次实验的心路历程,可谓是一波三折:
发现好像很多方法不知道怎么用-=> 在网上搜各种资料 =>越看越迷糊,不知道究竟该怎么写 => 请教同学问了一下思路 => 磕磕碰碰开始写,发现bug不少,错了好多好多的样子=> bug还没改完,发现好像快到交作业的截止时间了 => 越忙越乱,bug好像越改越多 => 突然知道原来报告是周六交,又惊又喜 => 既然时间还有很多,先好好看下《Java语言程序设计(基础篇)》上的内容 => 天呐!老师提到的建议的用法,明明在这本书上都有! => 改写自己的代码 => 沉下心慢慢修bug => 好不容易修完了,发现数据只数出来一组 => 得到老师的建议以后,改用了另外一种写法 => 发现这一组数据连输出都没法输出了 => 接着请教老师 => 好像答案还是不对 => 突然发现原来是 goods.txt 那个文本里,本来就已经有了内容... => 清空内容再试一次 => 终于成功写对了...
整个过程可谓是心路极其复杂,但也反映了我的基础还是不够扎实。比如说,当时在网上搜各种资料之前,如果能沉下心,先把《Java语言程序设计(基础篇)》的有关代码先敲一次,其实很多问题就根本不需要在网上漫无目的地搜,有些显得很基础的问题也就不需要问同学了。
说到底,这次还是想走捷径了,想着尽快把报告写完,而不是想着尽可能多从这次实验里,多学一点东西。这两种心态很不一样,而且求速成的心态往往不仅结果糟糕,而且也真的根本学不到什么东西。平时生活中,一定要尽力克服这种不良的心态!而且,现在渐渐发现,自己慢慢有了点心态浮躁的苗头了。可能因为现在学到的越来越多,需要记忆的也越来越多,很多东西都需要现学现用,但是有时候就很容易顺从自己的惰性,没有深入研究各个方法,只想着尽快写完报告。这样很不好,非常不好!在此提醒自己,一定要戒骄戒躁,可以写慢一些也无所谓,但是一定要有足够的耐心,慢慢琢磨每一个新遇到的方法的用法,不然,如果学完以后,下次想用的时候想不起来,那不也是相当于白学了嘛?!
心得:
在询问老师以后,才知道有些用法有专门的讲究,整理聊天记录如下:
l 每次DataInputStream和DataOutputStream在线程里面new的是新对象,然后每次重新读取的时候就会变成空白的文件了,所以读取不出来了
l 文件第一次读取时是不存在的,因此要捕捉这个异常。不能和写放在一起。
也正是因为,这两个细节没有考虑到,当时在无bug的情况下,我仍然被卡了很久,各种找错误...但是其实归根结底,也还是自己基础不够牢固,才会被这两个细节困扰那么久。
搜索的其他资料整理(超链接,可直接点击):
请教一个关于HashSet的问题。 [问题点数:40分,结帖人bicycleinbj]
如何得到hashset集合里的第n个元素?在list中是直接list a,然后a[n]就可以得到了 [问题点数:20分,
Java的wait(), notify()和notifyAll()使用小结
java异常处理之throw,throws,try和catch
在Java中怎样把StringBuffer中的字符串写入到文件
Java:bufferedReader.readLine()读取文件换行问题
JAVA中常用IO流类:BufferedReader和BufferedWriter
Java中readLine方法如何忽略行中的回车符\r [问题点数:20分,结帖人godshang]
java学习笔记之BufferedReader与BufferedWriter
-------------------------------------------------------------------------------------------------------------------------------------------------
碎碎念
这几天为了赶数学的各种DDL,还右各种编程的DDL,可谓是有些心力交瘁...突然有些后悔为什么要提前修概率论了,不过一想到,下个学期的编程课肯定更多,提前修也还是比较明智的决定。
但是又想到大约三个星期以后的六级,以及期末复习月,突然再次觉得,果然只有寒暑假和法定节假日能没有课内的牵挂,完全心无旁骛地学ACM,现在一回想,觉得暑假时真是太幸福了啊!~唉...能毫无牵挂地学习些什么的时间,真是越往后越奢侈啊...