[ Java学习 ] 线程实验1

题目:




-------------------------------------------------------------------------------------------------------------------------------------------------

代码:

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的情况下,我仍然被卡了很久,各种找错误...但是其实归根结底,也还是自己基础不够牢固,才会被这两个细节困扰那么久。

 

搜索的其他资料整理(超链接,可直接点击):

Set 遍历的三种方法

请教一个关于HashSet的问题。 [问题点数:40分,结帖人bicycleinbj]

Java 写文件实现换行

Java集合怎么一边删除一边遍历

如何得到hashset集合里的第n个元素?在list中是直接list a,然后a[n]就可以得到了 [问题点数:20分,

Java的wait(), notify()和notifyAll()使用小结

readUTF()和writeUTF()

java异常处理之throw,throws,try和catch

在Java中怎样把StringBuffer中的字符串写入到文件

Java:bufferedReader.readLine()读取文件换行问题

JAVA中常用IO流类:BufferedReader和BufferedWriter

Java中readLine方法如何忽略行中的回车符\r [问题点数:20分,结帖人godshang]

被readLine()折腾了一把

java学习笔记之BufferedReader与BufferedWriter

Scanner读取文件和StringBuffer读取文件

Java读取txt文件赋值到StringBuffer里

 

-------------------------------------------------------------------------------------------------------------------------------------------------

碎碎念

  这几天为了赶数学的各种DDL,还右各种编程的DDL,可谓是有些心力交瘁...突然有些后悔为什么要提前修概率论了,不过一想到,下个学期的编程课肯定更多,提前修也还是比较明智的决定。


  但是又想到大约三个星期以后的六级,以及期末复习月,突然再次觉得,果然只有寒暑假和法定节假日能没有课内的牵挂,完全心无旁骛地学ACM,现在一回想,觉得暑假时真是太幸福了啊!~唉...能毫无牵挂地学习些什么的时间,真是越往后越奢侈啊...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值