Javase之多线程(2)
多线程(2)
线程的生命周期
新建:创建线程对象
就绪:有执行资格,没有执行权
运行:有资格运行,有执行权
阻塞:由一些操作让线程处于改状态。没有执行资格,没有执行权,而通过另一些操作激活它,激活后处于就绪状态。
死亡:线程对象变成垃圾,等待回收
多线程的实现方式二
实现Runnable接口
步骤:
1.自定义类实现Runnable接口
2.重写run()方法
3.创建自定义类的对象
4.创建Theard类对象并把步骤3的对象作为参数传递。
class T1 implements Runnable{
@Override
public void run() {
for (int i = 0;i < 100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class runabletest {
public static void main(String[] args) {
T1 t = new T1();
//public Thread(Runnable target,String name)
Thread t1 = new Thread(t,"线程a");
Thread t2 = new Thread(t,"线程b");
// Thread t1 = new Thread(t);
// Thread t2 = new Thread(t);
// t1.setName("线程1");
// t2.setName("线程2");
t1.start();
t2.start();
}
}
实现接口的好处
1.可以避免由Java单继承带来的局限性。
2.适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效的分离,较好的体现了面向对象的思想。
线程安全问题
导致线程安全问题产生原因(也是判断程序是否出现线程安全问题的批准)
1.是否是多线程环境
2.是否有共享数据
3.是否有多条语句操作共享数据
解决方案
1和2的问题,是不能改变的。所以我们只能考虑改变3
思想:
把多条语句操作共享数据的代码包装成一个整体,让某个线程执行时,其它线程就不能执行。
解决安全问题方案1
同步代码块
格式:synchronized(对象){需要同步的代码块;}
对象是什么:任意对象
需要同步的代码是那部分:多条语句操作共享数据
synchronized (obj) {
while (n > 0) {
try {
Thread.sleep(100);
}catch (Exception e){
System.out.println("线程结束");
}
System.out.println(Thread.currentThread().getName() + "使用" + ":" + (n--));
}
}
注:同步可以解决安全问题的根本原因在对象上。该对象如同锁功能。多个线程必须使用同一把锁。
1.同步代码块的锁对象是任意对象
2.同步方法的格式:把同步关键字synchronized加到方法上
其锁对象是this
public synchronized void show(){
while (n > 0) {
try {
Thread.sleep(100);
}catch (Exception e){
System.out.println("线程结束");
}
System.out.println(Thread.currentThread().getName() + "使用" + ":" + (n--));
}
}
3.静态方法锁对象是类的字节码文件。
同步的特点
前提:多个线程
解决问题时注意:多个对象使用同一把锁。
好处:同步解决了多个线程的安全问题。
弊端:当线程较多时,因为每个线程都会去判断同步的锁,会浪费资源,降低程序运行效率。
如何保证集合是安全的
1.Vector是线程安全的
2.调用Collections中对应的方法
List<String> s = Collections.synchronizedList(new ArrayList<String>());
JDK5以后的Lock
为了直接的表达如何加锁和释放锁,JDK5以后提供了一个新对象Lock
Lock:
void lock();获取锁
void unlock() ;释放锁
ReentrantLock是Lock的实现类。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class T3 implements Runnable {
private int n = 100;
Lock l = new ReentrantLock();
@Override
public void run() {
while (true) {
l.lock();
if (n>0)
try {
Thread.sleep(100);
} catch (Exception e) {
System.out.println("线程结束");
}finally {
System.out.println(Thread.currentThread().getName() + "使用" + ":" + (n--));
l.unlock();
}
}
}
}
public class Locktest {
public static void main(String[] args) {
T3 t = new T3();
Thread t1 = new Thread(t,"线程a");
Thread t2 = new Thread(t,"线程b");
Thread t3 = new Thread(t,"线程c");
t1.start();
t2.start();
t3.start();
}
}
死锁问题
如果出现同步嵌套,就容易产生死锁问题。
问题描述
指在两个或两个以上的线程在执行过程中,因争夺资源而产生的一种相互等待的现象。
代码
class MyLock{
static Object objA = new Object();
static Object objB = new Object();
}
class MyTheard extends Thread{
boolean flag;
public MyTheard(boolean flag){
this.flag = flag;
}
public void run(){
if (flag){
synchronized (MyLock.objA){
System.out.println("if objA");
synchronized (MyLock.objB){
System.out.println("if objB");
}
}
}else {
synchronized (MyLock.objB){
System.out.println("else objB");
synchronized (MyLock.objA){
System.out.println("else objA");
}
}
}
}
}
public class Dielocktest {
public static void main(String[] args) {
MyTheard m1 = new MyTheard(true);
MyTheard m2 = new MyTheard(false);
m1.start();
m2.start();
}
}
Javase之多线程(2)的更多相关文章
- JavaSE总结--多线程
进程: 进程之间内存隔离,内存不共享. 线程: 可以共享内存. 每个线程都是一个栈. 多线程的好处: 1)防止程序阻塞. wait与notify的区别: 针对等待队列而言. wait:进入等待队列.必 ...
- Javase之多线程(1)
多线程(1) 多线程的概述 了解多线程之前需要先了解线程,而线程依赖于进程而存在,所以先了解进程. 什么是进程 进程就是正在运行的程序.是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内存空 ...
- JavaSE基础---多线程
进程:正在进行的程序.其实就是一个应用程序运行时的内存分配空间. 线程:进程中一个程序执行控制单元,一条执行路径.进程负责的事应用程序的空间的标识,线程负责的事应用程序的执行顺序. 进程和线程的关系: ...
- JAVASE(十七) 多线程:程序、进程、线程与线程的生命周期、死锁、单例、同步锁
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.程序.进程.线程的理解 1.1 概念 程序(program)是为完成特定任务.用某种语言编写的一组指 ...
- 如何自学 Java 开发
如何自学 Java 开发? 568赞同反对,不会显示你的姓名 李艾米IT路上学习 568 人赞同 Java Web前端技术 HTML 入门视频课程 1 HTML 简介 2 HTML基本结构[ 3 HT ...
- 带着新人学springboot的应用09(springboot+异步任务)
本来想说说检索的,不过不知道什么鬼,下载ElasticSearch太慢了,还是放一下,后面有机会再补上!今天就说个简单的东西,来说说任务. 什么叫做任务呢?其实就是类中实现了一个什么功能的方法.常见的 ...
- 数据库之JDBC
1.简单认识一下JDBC 1).JDBC是什么? java database connection java数据库连接 作用:就是为了java连接mysql数据库嘛 要详细的,就面向百度编 ...
- Android(java)学习笔记215:多线程断点下载的原理(JavaSE实现)
1. 为什么需要多线程下载? 服务器的资源有限,同时的平均地分配给每个客户端.开启的线程越多抢占的服务的资源就越多,下载的速度就越块. 2. 下载速度的限制条件? (1)你的电脑手机宽带的带宽 ...
- Android(java)学习笔记158:多线程断点下载的原理(JavaSE实现)
1. 为什么需要多线程下载? 服务器的资源有限,同时的平均地分配给每个客户端.开启的线程越多抢占的服务的资源就越多,下载的速度就越块. 2. 下载速度的限制条件? (1)你的电脑手机宽带的带宽 ...
随机推荐
- ASP.NET Core 2.2 WebApi 系列【一】搭建ASP.NET Core WebApi项目
一.步骤 从“文件”菜单中选择“新建”>“项目” . 选择“ASP.NET Core Web 应用程序”模板,再单击“下一步” . 将项目命名为 NetCoreWebApi,然后单击“创建” . ...
- selenium设置谷歌无头浏览器
from selenium import webdriver from selenium.webdriver.chrome.options import Options def Browse(): c ...
- Python 你见过三行代码的爬虫吗
------------恢复内容开始------------ 每次讲爬虫的时候都会从“发送请求” 开始讲,讲到解析页面的时候可能大部分读者都会卡住,因为这部分确实需要一点XPATH或者CSS选择器的前 ...
- MySQL触发器学习总结
1.What 触发器是MySQL响应DELETE,INSERT,UPDATE语句前后而自动执行的一条MySQL语句 2.Why(使用情形) 增加一个订单对应库存-1 删除一行在 ...
- Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果
场景 在Winform中实现弹窗式进度条 就是新建一个窗体,然后在窗体中加入进度条控件,然后在触发进度条的事件中将加载进度报告给 进度条控件. 注: 博客主页: https://blog.csdn.n ...
- iOS引导页(镂空效果)
推荐使用SDK:pod 'EAFeatureGuideView' 温馨提示:(引导的图片图标需要私人订制的可以用自己的,让UI提供) 参考链接:https://www.jianshu.com/p/c9 ...
- opencv-python 图像基础处理(四)
图像梯度-Sobel算子 Gx等于左边减去右边 Gy等于下减去上 可以得到像素值 dst = cv2.Sobel(src, ddepth, dx, dy, ksize)- ddepth:图像的深 ...
- QT--HTTP文件下载器
QT--HTTP文件下载器 1.pro文件添加 QT += core gui network 2.头文件 #include <QNetworkAccessManager> #i ...
- docker 修改镜像和容器的存放路径(最新自己实践了第三种方法)
docker info :查看docker的存储等相关信息. 将路径修改至挂载磁盘中 前提:磁盘已挂载成功 方法一: 1.停止docker 服务 service docker stop 2.备份数据到 ...
- NCCL(Nvidia Collective multi-GPU Communication Library) Nvidia英伟达的Multi-GPU多卡通信框架NCCL 学习;PCIe 速率调研;
为了了解,上来先看几篇中文博客进行简单了解: 如何理解Nvidia英伟达的Multi-GPU多卡通信框架NCCL?(较为优秀的文章) 使用NCCL进行NVIDIA GPU卡之间的通信(GPU卡通信模式 ...