JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1)
由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新。github传送门
一、创建新进程
由于这部分比较基础,这里不过多赘述,主要以代码呈现
1、java.lang.Thread的extends
public class MyThread extends Thread {
public void run() {
...
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); //启动新进程,调用run()
...
}
}
2、java.lang中的Runnable接口
public interface Runnable {
public abstract void run();
}
public class MyRunnable implements Runnable {
public void run() {
...
}
}
public class Main{
public static void main(String[] args) {
/*
*different to Thread
*创建MyRunnable的实例,再以该实例为参数创建Thread类的实例
*/
new Thread(new MyRunnable()).start();
...
}
}
3、java.util.concurrent.ThreadFactory中的线程创建
java.util.concurrent包中包含抽象化ThreadFactory接口
ThreadFactory factory = Executors.defaultThreadFactory();
//通过Executors.defaultThreadFactor获取ThreadFactory
factory.newThread(new myRunnable()).start()
二、简单操作和概念简述
具体更加细节的使用会在后面内容中提到,在这里只是做一个简单的罗列和概括,有一些我自己学习过程中总结的小提醒。
(1)Thread.sleep()
线程睡眠 Thread.sleep(long millis) 转到阻塞状态
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
(2)Thread.yield()
sleep 方法使当前运行中的线程睡眼一段时间,进入不可运行状态,且sleep 方法允许较低优先级的线程获得运行机会。
yield 方法使当前线程让出 CPU 占有权,但让出的时间是不可设定的。实际上,yield()方法对应了如下操作:先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU 的占有权交给此线程,否则,继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程。另外,yield() 方法执行时,当前线程仍处在可运行状态,所以,不可能让出较低优先级的线程些时获得 CPU 占有权。
(3)interrupt()
中断本线程
**本线程中断自己是被允许的,其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。
**如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。
**若线程在阻塞状态时,调用了它的interrupt()方法,那么它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。
**如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。 中断一个“已终止的线程”不会产生任何操作。
!!!!interrupt()并不会终止处于“运行状态”的线程!它会将线程的中断标记设为true。
(4)synchronized方法(同步方法)
synchronized void method() {
...
}
// is equal to
void method() {
synchronized(this) {
... //synchronized静态方法和动态方法在此例上有所区别,具体请自己查阅资料
}
}
声明一个方法,代表这个方法只能由一个线程运行
一个实例中的synchronized方法每次只能由一个线程运行,而非synchronized则可以由两个以上线程运行。
一个线程运行一个synchronized方法,则该进程获得了锁,其他进程就无法运行该方法,当该方法完成了,便会释放锁,一个一直等待锁的进程便会获得该锁,开始运行synchronized方法。
而非synchronized方法完全不受锁的影响,可以自由进入。
注意:每个实例都拥有一个独立的锁
(5)synchronized代码块
synchronized(expression) {
...
}
(6)等待队列
所有实例都拥有一个等待队列,它是在wait方法执行后停止操作的线程的队列
当由其他线程的notify()或notifyAll()方法唤醒,或有其他线程的interrupt()方法唤醒,或wait方法超时时,退出等待队列。
(7)wait
让线程进入等待队列
obj.wait();
若要执行wait方法,进程必须持有锁
(8)notify
从等待队列中取出一个线程(随机的)
线程必须持有要调用的实例的锁
(9)notifyAll
从等待队列中取出所有线程
wait、notify、notifyAll是Object类的方法,也是Thread类的方法
(10)join
等待线程终止
(11)setPriority() 、getPriority()
三 、Single Threaded Execution模式
1、synchronized
guarantee that only one thread can enter a given critical section of code
guarantee that all variables accessed inside the synchronized block will be read in from main memory and when the thread exits the synchronized block,all updated variables will be flushed back to main memory
(1)线程互斥处理(lock/unlock)
A获得锁-->A wait()-->A进入等待队列,释放锁-->B获得锁-->B notify()-->A退出等待队列,B仍然持有锁-->B释放锁-->A获得锁,正式开始执行
(2)同步处理
java内存模型确保某个进程进行unlock前所有写入操作对lock的线程可见。
2、SharedResource
在Single Threaded Execution模式中使用到了SharedResource作用的类
SharedResource可被多个线程访问,主要分为safeMethod和unsafeMethod,该模式就是为了保护unsafeMethod,使其同时只能由一个线程访问。
3、何时使用
(1)多线程程序
单线程显然没必要使用,并且调用synchronized方法比一般方法花费时间更多,会降低程序性能。
引用《图解Java多线程设计模式》中一个不太恰当的例子:在单线程程序中使用synchronized好比一个独居在家的人上厕所关门一样。
(2)SharedResource可能被多个线程访问时
(3)SharedResource的状态会发生变化
例如,Immutable模式就完全没必要使用
(4)需要确保安全性时
java的集合类大多非线程安全,请考虑
可以参考java.util.Collections的API文档
4、性能考虑
程序设计性能还是不得不考虑的一个环节
该模式主要在两方面会降低程序性能
(1)获取锁的花费
(2)线程conflict
一个小tips:
java.util.Hashtable和java.util.concurrent.ConcurrentHashMap二者功能相似,都是线程安全,其中Hashtable采用Single Threaded Execution模式,更易发生线程冲突,ConcurrentHashMap不易。
JAVA多线程学习笔记(1)的更多相关文章
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java 多线程学习笔记:生产者消费者问题
前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...
- java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...
- Java多线程学习笔记(一)
一 概述 一个进程只有一个至少会运行一个线程,Java中同样存在这样,在调用main方法的时候,线程又JVM所创建. package link.summer7c.test; public class ...
- java多线程学习笔记(四)
上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...
随机推荐
- Agiliq署名的免费python书籍
在他们的官网介绍中,说他们团队自2009年开始使用Django,Python,Postgres,Augular等工具来开发webapp,移动应用后台等.并且,他们还有一个Github组织,开源了相当多 ...
- Mac 装Sequel pro 连接 Mysql 8.0 失败、登录不了、loading问题
最近都没更新博客,零零散散的笔记也都没整理,so 觉得还是不放上来了. 高兴的是入手了期待好久的水果机,开始了各种捣鼓,好想大撸一下代码啊.... 回到正轨,刚装了mysql8.0, 想装下mysql ...
- springboot idea 代码更改自己编译设置
第一步:在pom.xml文件中添加springboot 编译依赖 <dependency> <groupId>org.springframework.boot</grou ...
- 算法工程师<编程题>
<编程题> 1.[Maximum Product Subarray 求最大子数组乘积] 这个求最大子数组乘积问题是由最大子数组之和问题演变而来,但是却比求最大子数组之和要复杂,因为在求和的 ...
- Linux telnet安装
为什么需要telnet? telnet就是查看某个端口是否可访问.我们在搞开发的时候,经常要用的端口就是 8080.那么你可以启动服务器,用telnet 去查看这个端口是否可用. Linux cent ...
- 设计模式 — 工厂方法模式(Factory Method)
在开发系统中,经常会碰到一个问题.现在需要实现的一些功能,但是这个功能模块以后一定是需要扩展的,那么现在开发中就不仅要实现现在的功能,还要考虑以后的扩展.那么为了系统的健壮,扩展就要遵循开闭原则(简单 ...
- Javascript执行上下文和执行栈
什么是执行上下文? 执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,JavaScript中运行任何的代码都是在执行上下文. 什么是执行栈? 执行栈,在其他编程语言中也被叫做 ...
- UMeditor控制多张图片上传顺序
多张图片上传的顺序,受到用户使用习惯.插件上传和插件插入页面顺序的影响. 估计是考虑到上传性能,官方没有提供UMeditor控制展示顺序的配置.在上传过程中,用户点击拖动的第一张图片,将作为文件数组中 ...
- Android Q 变更和新特性
安全和隐私变更 隐私保护是Android Q重要的主题之一,Android Q带来了一系列增强用户隐私保护的变更. 1 应用文件存储空间限制 应用访问限制是Android Q影响最大变更之一.在And ...
- spring boot 集成axis1.4 java.lang.NoClassDefFoundError: Could not initialize class org.apache.axis.client.AxisClient
pom配置: <dependencies> <dependency> <groupId>org.springframework.boot</groupId&g ...