Java编程思想笔记整理

Wesley13
• 阅读 712

实现线程的方法:
(1)继承thread(底层实现了runable)
(2)实现Runable
(3)Executor创建线程池
(4)实现Callable接口(带返回结果)
对于callable接口,可以通过FutureTask包装实现线程,也可以使用ExecutorService对象的submit实现。

使用executor创建线程池:(例)Executors.newCachedThreadPool返回一个ExecutorService对象(类似于命令模式)通过该对象的execute方法可以启动线程。
可带参数:ThreadFactory对象,批量生成线程
FixedThreadPool:分配指定数量的线程。
SingleThreadExecutor:类似于单例的fixed,顺序执行(序列化任务)
通常情况下整个系统的所有任务都由一个Executor创建和管理。调用shutdown方法可以防止新的任务被提交给该Executor,而之前提交的任务都会完成(未调用shutdown会导致线程挂起)
Callable接口:实现后任务会返回值,泛型规定返回类型(call方法中)
通过executorservice的submit方法调用callable或Runable对象,返回future对象。
(future:在未执行完时返回一个对象,可以通过isDone判断是否执行完。使用get方法来获取其中的值。但是在未执行完成前调用get方法可能会引起阻塞)

ScheduledThreadPoolExecutor:定期任务线程池,主要方法:scheduled

sleep:jdk5以后引入了TimeUnit.XX.sleep(X)的方式

守护线程创建的任何线程都是守护线程。当用户线程执行完毕之后,守护线程会自动结束(不会执行finally等,突然暴毙)

线程中的异常不会被trycatch处理,会直接抛出到控制台。解决方案:
线程设置异常处理器UncaughtExceptionHandler,实现该接口的对象作为参数。
推荐:使用ThreadFactory,内部为每一个线程附着异常处理器
全局使用一个时:调用静态方法:Thread.setDefaultUncaughtExceptionHandler设置

并发工具:

BlockingQueue(接口):内部同步,解决生产者消费者问题。为空时阻塞消费者,为满时阻塞生产者
主要方法:put take
实现类(例):DelayQueue PriorityBlockingQueue(非FIFO) ArrayblockingQueue SynchronousQueue (放和取交替) 等

DelayQueue:无界的BlockingQueue,放置实现了delayed接口的对象。该对象只有在到期时才能取走。可以理解为优先级队列的一种变体。根据到期时间的先后排序,决定取走顺序。没有到期任务时无法取出

CountDownLatch:(只触发一次)该对象初始化时可以设置计数值,通过调用该对象的countdown方法使其-1.
在此对象上调用await的所有线程都会阻塞,等待其计数值为0时全部唤醒。

CyclicBarrier(触发多次,通过reset重置计数值):设置一个栅栏动作(作为runable类型的构造参数传入,可通过匿名内部类设置),计数值达到0时首先自动执行,随后其他任务放行.(人满开车!)
通过调用await方法进行当前线程阻塞

Semaphore:类似于可以获取资源的通行证通过acquire获取通行证(表明资源被占用),通过release收回通行证(表明资源已经释放)。仅起到确保作用,释放和占用需要手动完成
当没有通行证(可用资源)时,semaphore对象将阻塞调用。

Exchanger:成对的线程交换对象(大多用于两个)
线程调用exchange方法,等待(此时阻塞)与其成对的线程调用exchange方法,成对调用后交换数据
主要方法:exchange,该方法返回值即为交换过来的值

CopyOnWriteArrayList:免锁容器,不会使用synchronized。允许并发的读写。在写入时创建底层数组的副本进行修改。完成后会将新数组换入,使其可见(注意完成后可见)
CopyOnWriteArraySet:使用CopyOnWriteArrayList实现免锁
ConcurrentHashMap和ConcurrentLinkedQueue:使用类似的技术,但是只会创建部分内容的副本
ConcurrentHashMap底层:数组,每个元素是个HashMap,分段进行数据处理
以上均不会抛出ConcurrentModificationException

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
灯灯灯灯 灯灯灯灯
3年前
阿里二面必备考题之Java并发!全面解析
一、使用线程有三种使用线程的方法:实现Runnable接口实现Callable接口继承Thread类实现Runnable和Callable接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过Thread来调用。可以理解为任务是通过线程驱动从而执行的。实现Runnable接口cpublicclass
Wesley13 Wesley13
3年前
java多线程实现的三种方式
JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。1、继承Thread类实现多线程继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现
浪人 浪人
3年前
一篇文章弄懂Java多线程基础和Java内存模型
文章目录一、多线程的生命周期及五种基本状态二、Java多线程的创建及启动1.继承Thread类,重写该类的run()方法2.通过实现Runnable接口创建线程类3.通过Callable和Future接口创建线程三、Java内存模型概念四、内存间的交互操作五、volatile和synchronized的
Wesley13 Wesley13
3年前
Java面试系列
实现多线程的方式继承Thread类,重写run方法,调用start方法启动线程实现Runnable接口,重写run方法,调用start方法启动线程实现Callable接口,重写call方法,并用FutureTask包装,在newThread中传入FutureTask,然后调用start方
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
JAVA多线程实现的四种方式
Java(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Flib.csdn.net%2Fbase%2Fjavaee)多线程实现方式主要有四种:继承Thread类实现Runnable接口、实现Callable接口通过FutureTask包装
Wesley13 Wesley13
3年前
Java多线程学习笔记
Java中创建多线程的三种方法1、继承Thread类创建线程2、实现Runnable接口创建线程3、使用Callable和Future创建线程\
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_