多线程(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)的更多相关文章

  1. JavaSE总结--多线程

    进程: 进程之间内存隔离,内存不共享. 线程: 可以共享内存. 每个线程都是一个栈. 多线程的好处: 1)防止程序阻塞. wait与notify的区别: 针对等待队列而言. wait:进入等待队列.必 ...

  2. Javase之多线程(1)

    多线程(1) 多线程的概述 了解多线程之前需要先了解线程,而线程依赖于进程而存在,所以先了解进程. 什么是进程 进程就是正在运行的程序.是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内存空 ...

  3. JavaSE基础---多线程

    进程:正在进行的程序.其实就是一个应用程序运行时的内存分配空间. 线程:进程中一个程序执行控制单元,一条执行路径.进程负责的事应用程序的空间的标识,线程负责的事应用程序的执行顺序. 进程和线程的关系: ...

  4. JAVASE(十七) 多线程:程序、进程、线程与线程的生命周期、死锁、单例、同步锁

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.程序.进程.线程的理解 1.1 概念 程序(program)是为完成特定任务.用某种语言编写的一组指 ...

  5. 如何自学 Java 开发

    如何自学 Java 开发? 568赞同反对,不会显示你的姓名 李艾米IT路上学习 568 人赞同 Java Web前端技术 HTML 入门视频课程 1 HTML 简介 2 HTML基本结构[ 3 HT ...

  6. 带着新人学springboot的应用09(springboot+异步任务)

    本来想说说检索的,不过不知道什么鬼,下载ElasticSearch太慢了,还是放一下,后面有机会再补上!今天就说个简单的东西,来说说任务. 什么叫做任务呢?其实就是类中实现了一个什么功能的方法.常见的 ...

  7. 数据库之JDBC

    1.简单认识一下JDBC 1).JDBC是什么? java database connection       java数据库连接 作用:就是为了java连接mysql数据库嘛 要详细的,就面向百度编 ...

  8. Android(java)学习笔记215:多线程断点下载的原理(JavaSE实现)

    1. 为什么需要多线程下载?     服务器的资源有限,同时的平均地分配给每个客户端.开启的线程越多抢占的服务的资源就越多,下载的速度就越块. 2. 下载速度的限制条件? (1)你的电脑手机宽带的带宽 ...

  9. Android(java)学习笔记158:多线程断点下载的原理(JavaSE实现)

    1. 为什么需要多线程下载?     服务器的资源有限,同时的平均地分配给每个客户端.开启的线程越多抢占的服务的资源就越多,下载的速度就越块. 2. 下载速度的限制条件? (1)你的电脑手机宽带的带宽 ...

随机推荐

  1. Java描述设计模式(10):组合模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.文件系统 下图是常见的计算机文件系统的一部分. 文件系统是一个树结构,树上长有节点.树的节点有两种: 树枝节点 即文件夹,有 ...

  2. git push 时用户的配置

    Pycharm临时配置git提交的账户:git 修改当前的project的用户名的命令为:git config user.name 你的目标用户名**;git 修改当前的project提交邮箱的命令为 ...

  3. Java生鲜电商平台-电商数据运营统计与分析

    Java生鲜电商平台-电商数据运营统计与分析 今天分享将会分为以下几个方面来阐述: 1. 作为运营我们需要统计与分析的几个核心数据是什么? 2. 核心数据对业务的指导价值在哪里呢? 3. 作为产品PM ...

  4. Vue.js+vue-element搭建属于自己的后台管理模板:更深入了解Vue.js(三)

    前言 上一章我们介绍了关于Vue实例中一些基本用法,但是组件.自定义指令.Render函数这些放到了本章来介绍,原因是它们要比前面讲的要难一些,组件是Vue.js最核心的功能,学习使用组件也是必不可少 ...

  5. 使用NodeJS模块-第三方提供的模块(什么是npm)

    第三方开发者提供的模块 第三方模块是由NodeJS社区或第三方个人开发的功能模块,这些功能模块以软件包的形式存在.被发布在npmjs注册表中.npmjs是一个注册中心,所有软件包的信息都会被记录到该注 ...

  6. 用了这么久HTTP, 你是否了解Content-Length?

    摘要: 理解HTTP协议... 原文:用了这么久HTTP, 你是否了解Content-Length和Transfer-Encoding ? 作者:朴瑞卿的博客 由Content-Length导致的问题 ...

  7. 解决element-ui的表格设置固定栏后,边框线消失的bug

    如上图所示,边框线消失了,解决方法如下 添加css代码,如果是修改全局,则到全局样式文件添加 .el-table__row{ td:not(.is-hidden):last-child{ right: ...

  8. SSH远程管理

    目录 SSH远程管理 ssh功能 SSH相关命令 Xshell连接不上虚拟机 scp命令 SSH验证方式 优化 免交互expect[扩展] 免交互sshpass[扩展] 简易跳板机 小结 SSH远程管 ...

  9. 远程访问阿里云服务器jupyter

    官网链接 一.pip安装jupyter安装Anaconda的话,会自动按照jupyter,就不需要再使用pip安装了 pip3 install jupyter 二.生成jupyter notebook ...

  10. C Primer Plus 第六版—— 6.16 编程练习题(附代码)

    1.编写一个程序,创建一个包含26个元素的数组,并在其中存储26个小写字母.然后打印数组的所有内容. #include <stdio.h> int main(void) { int num ...