引言------首先我们发现一个bug:当多个线程共享一个runnable的运行资源时,会出现抢占资源导致程序出现异常的情况,最经典的就是跨银行账户取款出现透支的情况,即线程不同步的弊端,所以实现线程同步很有必要.
1.实现线程同步
当两类或者多个线程需要访问同一个资源时,需要以某种顺序来确保该资源在某一时刻只能被一个线程使用的方式称为线程同步.采用同步来控制线程的执行有两种方式,即同步方法和同步代码块,两种方法都使用synchronized关键字实现.
这是第一种使用关键字synchronized方法,格式为
synchronized(任何对象,基本数据类型需要转换为包装类,通常设置Byte b=1;){需要保护的代码块}这是第二种使用关键字方法,直接将方法用synchronized修饰,格式为
访问修饰符(public/protected/privated/default)+synchronized+返回值+(形参){方法体}
synchronized+访问修饰符(public/protected/privated/default)+返回值+(形参){方法体}
2.案例-----wordcatch的多线程实现
首先,我们在单线程运行下思考如何实现读取一个文本文件中的文本内容并检索出各个词语出现的次数.
单线程思路:
1.首先利用BufferedReader的readline()方法读取指定文件的文本内容.(结合所学的I/O文件操作流程)
2.利用StringBuffer工具的append()方法将文件的文本数据存储到集合中.
3.利用String的trim()方法删除文本中开头结尾空白(空格)再使用split("\\s")方法获得文本数据中单个单词或词组(split方法是根据形参内容将字符串分割为相应数组,数组内容有序)
4.核心代码思考,如何使用集合框架去寻找重复内容(集合框架有Collection接口和Map两大父接口),想到contains()方法,再想到使用Map框架,使用多态创建一个treeMap对象(数据容器)接收字符串和该字符串的出现次数.
5.使用循环遍历数组,将字符串作为treeMap的key值录入,将出现次数(int值)作为value值录入,treeMap设置同个key对应的value值会被后来的录入覆盖掉,利用此特性,每找到一次覆盖一次value的值((int value )++).如果contains()结果是false,则put()方法新加入一个key值,并将value基础值设为1.
6.最后遍历Map集合获取每个value值
多线程思路:
将单线程思路写入线程的run()方法体中,使用线程池同时运行多个线程