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)你的电脑手机宽带的带宽 ...
随机推荐
- ETCD:TLS
原文地址:TLS etcd支持用于客户端到服务器以及对等方(服务器到服务器/集群)通信的自动TLS以及通过客户端证书的身份验证. 要启动并运行,首先要获得一个成员的CA证书和签名密钥对. 建议为集群中 ...
- Spring Boot 2 快速教程:WebFlux 集成 Thymeleaf(五)
号外:为读者持续整理了几份最新教程,覆盖了 Spring Boot.Spring Cloud.微服务架构等PDF.获取方式:关注右侧公众号"泥瓦匠BYSocket",来领取吧! 摘 ...
- ASP.NET Core MVC配置差异(3.0和2.X)
https://www.cnblogs.com/lonelyxmas/p/10934388.html net core 2.x MVC配置 public void ConfigureServices( ...
- In .net 4.8,calculate the time cost of serialization in BinaryFormatter,NewtonSoft.json,and System.Text.Json.JsonSerializer.Serialize
using ConsoleApp390.Model; using Newtonsoft.Json; using System; using System.Collections.Generic; us ...
- FCC---Use the CSS Transform scale Property to Change the Size of an Element
To change the scale of an element, CSS has the transform property, along with its scale() function. ...
- Vue组件通信的几种方法
上一节说到,vue.js是允许子组件通过props接受父组件的信息,但是不允许父组件通过props接受子组件的信息 1. $emit()和on 当子组件需要向父组件传递数据时,就要用到自定义事件. 使 ...
- vue中使用props传递参数
通常,父组件的模板中包含子组件,父组件要正向地向子组件传递数据或参数,子组件收到后根据参数的不同来渲染不同的内容,或者执行操作. 这个正向传递数据的过程是通过props来实现的. 在组件中,子组件使用 ...
- docker 存储卷 Volumes
一,docker容器面临的困境: 容器运行中产生的数据,是放到容器栈的最顶层,当容器停止并被删除后,这些数据就被删除了. docker采用COW(写时复制)策略,导致性能低下.比如有个mysql容器, ...
- 关于学习和开发Android的一点体会
在谷歌中国安卓开发官网的 https://developer.android.google.cn/guide 之下有许多开发资料,有讲解,和例子.分门别类很清楚. 在 https://develope ...
- 201871010114-李岩松《面向对象程序设计(java)》第十六周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...