热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java之多线程学习笔记

1.理解程序,进程,线程的概念程序可以理解为静态的代码进程可以理解为执行中的程序线程可以理解为进程的进一步细分,程序的一条执行路径2.如何创建java程序的线程方式一:继承于Thread类1

1.理解程序,进程,线程的概念

程序可以理解为静态的代码

进程可以理解为执行中的程序

线程可以理解为进程的进一步细分,程序的一条执行路径

2.如何创建 java 程序的线程

方式一:继承于Thread 类

//1. 创建一个继承 Thread 的子类
class PrintNumber extends Thread {
// 2.实现接口的抽象方法
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}

}

public class TestThread1 {
public static void main(String[] args) {
//3.创建子类的对象
PrintNumber p1 = new PrintNumber("线程1");
PrintNumber p2 = new PrintNumber("线程2");
//设置优先级
p1.setPriority(Thread.MAX_PRIORITY);//最大值为10
p2.setPriority(Thread.MIN_PRIORITY);//最小值为1
//4. 调用线程的start(): 启动此线程; 调用相应的run()方法
t1.start();
t2.start();
}
}


方式二: 实现Runnable接口

//1. 创建一个实现了Runnable 接口的类
class PrintNumber implements Runnable {
// 2.实现接口的抽象方法
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}

}

public class TestThread1 {
public static void main(String[] args) {
//3.创建一个Runnable 接口实现类的对象
PrintNumber p = new PrintNumber();
//4.将此对象座位形参传递给 Thread类的构造器中,创建Thread类的对象
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();

}

}


两种方式的对比:

实现的方式较好:

        ①解决了单继承的局限性

②如果多个线程有共享数据的话,建议使用实现的方式,同时,共享数据所在的类可以作为Runnable接口的实现类。

线程里的常用方法: start()   run()  currentThread() setName(Strign name)   yeild()join()  sleep() isAlive();

getPriority()setPriority(int i)   wait()   notify()    notifyAll()

3.线程的生命周期


4.线程的同步机制

前提: 如果创建的多个线程存在着共享数据,那么就有可能出现线程的安全问题:

当其中一个线程操作共享数据是,还未操作完成,另外的线程就参与进来,导致对共享数据的操作出现问题。

解决方式:要求一个线程操作共享数据时,只有其完成操作完成共享数据,其它线程才有机会执行共享数据。

方式一:同步代码块

synchronized(同步监视器){

//操作共享数据的代码

}

注:1). 同步监视器:俗称锁,任何一个类的对象都可以充当锁。要想保证线程的安全,必须要求所有的线程共用同一把锁!

2). 使用实现Runnable接口的方式创建多线程的话,同步代码块中的锁,可以考虑是this,如果使用继承Thread类的方式,慎用this!

3). 共享数据: 多个线程需要共同操作的变量。 明确哪部分是操作共享数据的代码。

方式二: 同步方法 : 将操作共享的方法声明为synchronized.

比如: public synchronized void show(){//操作共享数据的代码 }

注:1). 对于非静态的方法而言,使用同步的话,默认锁为:this。 如果使用在继承的方式实现多线程的话,慎用!

2). 对于静态的方法,如果使用同步,默认的锁为: 当前类本身。


总结: 释放锁: wait()

不释放锁: sleep()yield() suspend()

死锁:不同的线程分别占用对方需要的同步资源部放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁

死锁是我们在使用同步时,需要避免的问题!

5.线程的通信 : 如下的三个方法必须使用在同步代码块或同步方法中!

wait() : 当在同步中,执行到此方法,则此线程“等待”,直至其它线程执行notify()的方法,将其唤醒,唤醒后继续其wait()后的代码。

notify()/notifyAll() : 在同步中,执行到此方法,则唤醒其它的某一个或所有的被wait的线程


推荐阅读
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
author-avatar
82年的老代码
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有