Java并发计算知识点+代码

JAVA多线程

任务(线程的执行体)、创建和运行线程

定义任务

  • 继承Thread类 (将任务和线程合并在一起)
  • 实现Runnable接口 (将任务和线程分开)
  • 实现Callable接口 (利用FutureTask执行任务)
//定义线程
class T extends Thread{        //extends继承父类
    @Override
    public void run(){
    }
}

class R implements Runnable{    //implements为实现接口,必须在类内重写才能使用方法
    @Override
    public void run(){
    }
}

class C implements Callable<Sting>{
    @Override
    public String call() throws Exception{
        return ;
    }
}

//启动
new T().start();

new Thread(new R()).start();  //R的实例作为Thread的target创建Thread对象

FutureTask<String> target = new FututreTask<>(new C());  //结合FutureTask可获取线程执行结果
new Thread(target).start();
log.info(target.get());
  • 实现Runnable接口继承Thread类所具有的优势:
  1. 适合多个相同的程序代码的线程去处理同一个资源
  2. 可以避免java中的单继承的限制
  3. 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
  4. 线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类
  • Callable和Future的优势: 可以在任务执行完毕之后得到任务执行结果, 而Runnable和Thread必须通过共享变量或者使用线程通信的方式获取执行结果

Future接口

Future接口表示异步任务,是还没有完成的任务给出的未来结果.
Callable用于产生结果,Future用于获取结果。

Future三种功能:

  1. 能够取消任务。 cancel()
  2. 判断任务是否完成。 isDone()
  3. 能够获取任务执行结果。 get()

线程池

线程池是一种管理线程的工具。预先创建一些线程,任务提交时直接执行.
既可以节约创建线程的时间,又可以控制线程的数量。

ExecutorService接口(继承Executor接口)

//创建
ExecutorService es = Executors.newFixedThreadPool(int);  //定长,可控制最大并发数,超出等待
newCachedThreadPool(int);  //超出可灵活回收空线程,若无可回收则新建
newScheduledThreadPool();  //定长线程,支持定时及周期性任务执行
newSingleThreadExecutor();  //单线程化,保证任务按照顺序(FIFO,LIFO,优先级)执行

//运行
es.execute(Runnable);    //不能获得任务执行结果
es.submit(Runnable);    //返回Future对象  future.get()可检查任务完成
es.submit(Callable);    //返回future对象并且call()有返回值
es.invokeAny();   //传入callable集合
es.invokeAll();

//关闭
es.shutdown();

案例-多文件词频统计

Java 多线程——统计文件中各单词数量 - 简书

Java统计字符串中每个字符(单词)个数_SCGH_Fx的专栏-CSDN博客_java统计字符串中单词个数

ArrayList类  (实现List接口)

动态数组

ArrayList arr = new ArrayList();  //参数可以为数组或数值或者为空

arr.add(int index,  Object obj);  //添加元素
arr.remove();   //根据对象或者下标
arr.size();
arr.set(int index, Object obj);  //替换元素
arr.clear();
arr.get(int index);  //查找元素

Hashmap  (实现Map接口)

HashMap<Integer, String> mapper = new HashMap<Integer,String>();

mapper.put(1, "hello");    //添加元素  重复put会替换旧值
mapper.get(key);    //获取元素
mapper.getOrDefault(Object key, V defaultValue);    //获取key对应value,找不到key则返回默认值
mapper.remove(key);    //删除元素
mapper.containsKey();    //检查是否存在key映射 返回布尔
mapper.keySet();    //返回key集合
mapper.entrySet();    //返回包含所有映射关系的Map.Entry类型的Set集合

Map.Entry

Map是java中的接口,Map.Entry是Map的一个内部接口。此接口为泛型,定义为Entry<K,V>。它表示Map中的一个实体(一个key-value对)接口有getKey()getValue()方法

//map不能直接使用迭代器因为map没有像set继承
//map.entry对map遍历
//方法一
Map map = new HashMap();
Irerator iterator = map.entrySet().iterator();
while(iterator.hasNext()) {
    Map.Entry entry = iterator.next();
    Object key = entry.getKey();        //获得键值对的键
}

//方法二 for-each循环
for(Map.Entry<Integer, Integer> entry : mapper.entrySet()) {
    entry.getValue();    //获得键值对的值
}

//方法三  遍历key集合(这里假设键是string)
for(String key: mapper.keySet()){
}

Java的Mapreduce实现

Main Hadoop classes: Configuration, Job, Mapper, Reducer, Combiner

Job job= Job.getInstance(conf, "")


'''Mapper'''
map(WritableComparable, Writable, Context)
context.write(K, V)

'''Reducer'''
reduce(WritableComparable, Iterator<Writable>, Context)
context.write(K, V)

Linux环境运行: 

#编译
javac WordCount.java
jar cf wc.jar WordCount*.class

#运行
hadoop jar wc.jar WordCount input output

Java的MapReduce实现:Mapper详解 - 简书


操作系统 进程线程模型

进程

基本属性进程是一个可拥有资源的独立单位,又是一个可以独立调度和分派的基本单位。

  1. 创建进程:必须为其分配所有资源(除CPU外),包括内存空间、I/O设备以及建立相应的数据结构PCB。
  2. 撤销进程:必须先对这些资源进行回收操作,然后在撤销PCB。
  3. 进程切换:由于要保留当前进程的CPU环境和设置新选中进程的CPU环境,为此需要花费不少的CPU时间。

进程是一个资源拥有者,因而在进程的创建、撤销和切换中,系统必须为之付出较大的时空开销。

创建背景:如果将作为调度和分派的经本单位不同时作为独立分配资源的单位,以使轻快运行;而对拥有资源的基本单位,又不频繁地对之进行切换。

线程

线程是进程中的一个实体,是CPU调度和分派的基本单位。

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。

线程也同样有三种就绪、等待和运行基本状态。

线程的属性

  • 每一个线程有一个唯一的标识符和一张线程描述表,记录了线程执行的寄存器和栈等现场状态。
  • 不同的县城可以执行相同的程序,同一个服务程序被不同用户调用时操作系统为它创建不同的线程。
  • 同一个进程中的各个线程共享进程的内存地址空间。
  • 线程是处理器的独立调度单位,多个线程是可以并发执行的,在单个CPU的计算机系统中,各个线程可交替的占用CPU;在多个CPU计算机系统中,各个线程可同时占用不同的CPU,若各个CPU同时为一个进程内的各种线程服务是可以缩短进程的处理时间。
  • 一个线程被创建后便开始了它的生命周期,直至终止,县城在生命周期内会经历等待、就绪和运行等各种状态变化。

线程与进程的比较

线程具有许多传统进程所具有的特征,故又称为轻量级进程或者是进程元,把床听的进程称为重量级进程。

  1. 调度:在传统的操作系统中,拥有资源的基本单位和独立调度、分派的基本单位都是进程。而在引入县城的操作系统中,则把线程作为调度和分派的基本单位。同一进程中,线程切换不会引起进程切换;而在由一个进程中的线程切换到另一个进程中的线程时,将会引起进程切换。
  2. 并发性:在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间也可以并发执行。很有效的使用系统资源和提高系统的吞吐量。
  3. 拥有资源:线程的自己不拥有系统资源,但它可以访问其隶属进程的资源,可供同一进程的其他所有线程共享。
  4. 系统开销:由于在创建或撤销进程时,系统都要为之分配或回收资源。因此,操作系统所付出的开销将显著地大于在创建或撤销线程时的开销。

参考:

https://blog.csdn.net/qq_35598736/article/details/108431422

Java多线程学习(吐血超详细总结)_Evankaka的专栏-CSDN博客_java多线程

Java多线程学习(一)- Java线程的生命周期与创建方式_江湖人称小程的博客-CSDN博客

java Map及Map.Entry详解_xjk201的博客-CSDN博客_java map.entry

 操作系统 进程线程模型 线程模型 - 云+社区 - 腾讯云

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值