Java_【多线程_①】

进程与线程

进程: 操作系统程序一次执行过程(程序执行的一个周期)

现代操作系统资源分配最小单元 资源分配最主要的内存
操作系统为每一个进程分配内存互不干扰
线程:操作系统进程的子任务
现代操作系统任务分配的最小单元
在一个进程中的所有线程共享这个进程的资源

区别

1.进程:是操作系统资源的最小单元 .线程:任务分配的最小单元
2.进程启动与销毁代价大 线程启动或销毁代价小
3.进程之间相互独立相互通信比线程之间通信复杂

高并发:同一时刻 并发访问的线程数量非常高
高可用:系统不宕机 可用时间长
分布式:一个程序分别部署在多台机器

主方法 主线程
使用命令 java 启动JVM进程
Java多线程实现
Java.lang.Thread 多线程核心类
实现多线程的方法
无论使用哪种方法创建线程 启动线程都使用Thread提供的start方法 run()方法不能有用户调用
Thread类本身实现Runnable 与用户自定义贤臣各类共同完成线程操作 代理设计模式
其中Thread类辅助操作 包括线程的资源调度等人 自定义线程完成真实的业务

(1)extends Thread 类 而后复写Run方法(线程任务)

Java.lang.Thread
一个线程的 start 方法只能被执行一次 执行多次 会抛出一个非受查异常llegalThreadStateException
在底层 由调用shart0 本地方法进入JVM分配空间,JVM_StartThread 调用底层然后去调用Thread中的run方法

(2)Runnable()接口实现多线程

该接口可以使用Lumdada表达式 通过实现Runnable 接口
前两者区别:
1.继承Thread 存在单继承限制Thread也实现Runnable接口 实现Runnable接口的方式更加灵活
2.通过实现Runnable 更好实现的多线程共享资源票子不重复 不会发生3个人60张票子

(3)实现Callable接口 覆写call方法

弥补Run()方法没有返回值 call()方法执行后有返回值
Future 接收Callable接口的返回值
V get() 接收Callable的返回值

(4)线程池

1.降低资源消耗
2.提高响应速度
3.提高线程的可管理性

线程池工作流程

(1)当一个任务提交给线程池时,先判断核心池的线程数量是否达到配置的corePoolSize,若未达到创建新的线程并将其置入新的线程池中。否则,判断核心池是否有空闲线程,若有分配任务执行,否则进入步骤二
(2)判断当前线程池中的数量有没有达到线程池中的最大数量maximumPoolSize(),若没有,将创建的新的线程志新任务并且置放与线程池中。否则进入步骤三
(3)阻塞队列中判断阻塞队列是否满,若未满,将任务置于阻塞队列,否则步骤四
(4)调用拒绝策略打回任务
a)默认为抛出异常给用户 AbortPolicy

核心两个接口void execute(Runnable command);

两个接口实现 1个继承 1个线程池 都使用start()方法启动

常用的阻塞队列
ArrayBlockQueue 基于数组
LinkedBlockingQueue(内置线程池 使用) 基于链表
SynchronousQueue 不存储元素的无界队列 一个元素的插入操作同时等待一个元素的删除操作 否则插入操作一直阻塞当前线程
内置线程池CacheThreadPool() 就采用次队列

PriorityBlockPoolSize 优先级队列

FutureTask() 可以保证多线程场景下,任务只能一个线程自行一次,其他线程不再执行此任务
Fiture中的get方法会阻塞当前线程直达取得Callable对象

线程池中的线程被包装为Worker工作线程 具备可重复执行任务的能力

合理配置线程池:配置线程池核心池与最大池的数量
CPU密集型 ncpu数量+1
IO密集型 2
n*cpu数量

JDK内置四大线程池
Executor //线程池的工具类
Executors.newFixedThreadPool(); 固定大小线程池
/*
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}

/
Executors.newSingleThreadExecutor(); 单线程池
/

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
*/
当多线程场景下需要任务串行执行

Executors.newCachedThreadPool(); 缓存池
/*
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
当任务提交速度大于线程执行速度会不断创建新线程有可能无限创建线程会将内存写满 合理的匹配两个
当任务提交速度小于线程执行速度会创建有限个若干线程

适用于负载小的服务器,或执行很短期线程
*/

Executors.newScheduledThreadPool()
/*
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
return e.scheduleAtFixedRate(command, initialDelay, period, unit);
}
延迟delay个单元后每周period时间单元执行一次

JDK1.7 任务分工 Fork/join
JDK1.8 StameLock
JUC 闭锁CountDownLatch 循环展览 信号量 交换器

Java常用的线程操作
(1)线程名称的方法

1.命名和取得
①Public static native Thread currentThread(); 拿到当前正在执行的线程对象
命名
②Public Thread(Runnabke target,String name)
③Public final synchroized void setName(String name)
④Public final String getName() 取得线程名字

(2)线程休眠 sleep() 方法

Public static void sleep(long time) 单位毫秒
让线程暂缓执行,到时间之后,在恢复执行。 线程休眠会是当前线程立刻交出cpu 但是不会释放对象锁。

(3)线程让步 yield()方法

暂停当前正在执行的线程对象,并且执行其他线程,当前cpu不会立即交出cpu,交出时间由系统决定。只能让拥有相同优先级的线程获取cpu
不释放对象锁

(4)线程等待join() 方法

一个线程1需要等待线程2执行完毕,在线程1中调用线程2.join() 等待线程2执行完毕在执行1.在那个线程中调用那个线程阻塞

线程停止

1.设置一个标志位
阻塞状态下就停不下来 无法修改标志位 无法处理线程阻塞式的问题
2.调用Thread提供的Stop方法 强行关闭线程
不推荐使用 因为强制退出会导致线程安全问题

3.通过Thread类调用interrupt() 方法

(1)若线程中 没有 sleep wait join 类似的方法让线程进入阻塞状态 并不会真正的中断线程,只会简单的将线程的状态 变为 interrupt状态
Thread类中的提供 isInterrupted()方法可以检测线程是否为中断状态
(2)若线程中调用了 阻塞线程的方法 sleep wait join 会将线程的状态变为true 再调用interrupt()会抛出异常InterrupterException 同时将线程的状态还原为 false
线程优先级
向JVM建议无法控制优先级
1.设置优先级 setProiority(int newPriority)
2.获得一个优先级 getProiority()
3… 最高优先级:public final static int MAX_PRIORITY = 10;
4. 中等优先级:public final static int NORM_PRIORITY = 5;
5. 最低优先级:public final static int MIN_PRIORITY = 1;
在父线程中创建子线程(在一个线程中创建另一个线程)默认子线程与父线程相同优先级

两类线程

用户线程
运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程
守护线程
守护线程是指在程序运行的时候在后台提供一种通用服务的线程
比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因 此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。
只要JVM种还有至少一个用户线程 守护线程一直工作 为陪伴线程
默认创建的线程使用户线程
1.创建守护线程
通过Thread.setDaemon()将用户线程设置为守护线程
经典 守护线程 gc 垃圾回收线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用AngularJs编写的简单 益智游戏(附源代码)  这是一个简单的 javascript 项目。这是一个拼图游戏,也包含一个填字游戏。这个游戏玩起来很棒。有两个不同的版本可以玩这个游戏。你也可以玩填字游戏。 关于游戏 这款游戏的玩法很简单。如上所述,它包含拼图和填字游戏。您可以通过移动图像来玩滑动拼图。您还可以选择要在滑动面板中拥有的列数和网格数。 另一个是填字游戏。在这里你只需要找到浏览器左侧提到的那些单词。 要运行此游戏,您需要在系统上安装浏览器。下载并在代码编辑器中打开此项目。然后有一个 index.html 文件可供您修改。在命令提示符中运行该文件,或者您可以直接运行索引文件。使用 Google Chrome 或 FireFox 可获得更好的用户体验。此外,这是一款多人游戏,双方玩家都是人类。 这个游戏包含很多 JavaScript 验证。这个游戏很有趣,如果你能用一点 CSS 修改它,那就更好了。 总的来说,这个项目使用了很多 javascript 和 javascript 库。如果你可以添加一些具有不同颜色选项的级别,那么你一定可以利用其库来提高你的 javascript 技能。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值