【JAVA基础篇】多线程

学习Java的多线程知识之前,我们先来了解一下进程和线程的概念,以及他们之间的关系。

进程

基本概念

进程是具有独立功能的程序在某个数据集合上的一次执行过程。

特点

  1. 进程是操作系统进行资源分配的基本单位。
  2. 每个进程都有自己的地址空间,即进程空间。

线程

基本概念

一个进程内部的一个执行单元,它是程序中的一个单一的顺序控制流程。

特点

  1. 自己不拥有系统资源,只拥有一点儿在运行过程中必不可少的资源。与同一个进程下的其他所有线程共享进程所拥有的全部资源。
  2. 线程是进程中的一个实体,是被操作系统独立调度的基本单位。

进程和线程的联系和区别

进程是资源分配的基本单位,线程是调度的基本单位。进程包含线程,线程共用进程的资源。

Java实现多线程

有四种方式:

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口,并与FutureTask结合使用
  4. 线程池

继承Thread类

package com.cc.thread;public class ThreadDemo extends Thread{public ThreadDemo(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println(this.getName()+i);}}public static void main(String[] args) {new ThreadDemo("张三").start();new ThreadDemo("李四").start();}}

实现Runnable接口

package com.cc.thread;public class RunableDemo implements Runnable {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public RunableDemo(String name) {super();this.name = name;}@Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println(this.getName()+i);}}public static void main(String[] args) {new Thread(new RunableDemo("张三")).start();new Thread(new RunableDemo("李四")).start();}}

实现Callable接口,并与FutureTask结合使用

package com.cc.thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class CallableDemo {public static void main(String[] args) {CallableImpl callableImpl = new CallableImpl();FutureTask<Integer> futureTask = new FutureTask<Integer>(callableImpl);Thread thread = new Thread(futureTask);thread.start();try {int sum = futureTask.get();System.out.println(sum);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}private static class CallableImpl implements Callable<Integer>{@Overridepublic Integer call() throws Exception {int sum = 0;for (int j = 0; j <= 100; j++) {System.out.println(Thread.currentThread().getName()+":"+j);sum += j;}return sum;}}}

运行上面的代码,我们发现每次返回的结果都是5050(这么巧的吗?难道每次call方法瞬间就执行完了,然后再执行的int sum = futureTask.get();),其实如果线程的call方法还未执行完毕,futureTask.get()方法会一直阻塞,直到call()方法执行完毕才能取到返回值。

线程的生命周期

通过查看Thread内部类State的源码,我们知道线程有6中状态,分别是:

    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;

Thread内部类State的源码

    public enum State {/*** Thread state for a thread which has not yet started.*/NEW,/*** Thread state for a runnable thread.  A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from the operating system* such as processor.*/RUNNABLE,/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {@link Object#wait() Object.wait}.*/BLOCKED,/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* <ul>*   <li>{@link Object#wait() Object.wait} with no timeout</li>*   <li>{@link #join() Thread.join} with no timeout</li>*   <li>{@link LockSupport#park() LockSupport.park}</li>* </ul>** <p>A thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called <tt>Object.wait()</tt>* on an object is waiting for another thread to call* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on* that object. A thread that has called <tt>Thread.join()</tt>* is waiting for a specified thread to terminate.*/WAITING,/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* <ul>*   <li>{@link #sleep Thread.sleep}</li>*   <li>{@link Object#wait(long) Object.wait} with timeout</li>*   <li>{@link #join(long) Thread.join} with timeout</li>*   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>*   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>* </ul>*/TIMED_WAITING,/*** Thread state for a terminated thread.* The thread has completed execution.*/TERMINATED;}

 关于线程状态的详细描述和他们之前的相互转换请参考4 Java线程的状态及主要转化方法 · 深入浅出Java多线程

线程方法总结

start使线程由新建状态进入就绪状态,只能调用一次,否则会报IllegalThreadStateException
run线程执行体,由系统调用
isAlive新建和死亡状态会返回false,其他状态返回true
interrupt设置线程中断状态为true
interruptedstatic方法,先返回当前线程中断状态,然后设置线程中断状态为false
isInterrupted返回当前线程中断状态
sleepstatic native方法,使线程进入阻塞状态(不会释放同步锁)
currentThreadstatic方法,该方法返回当前正在使用CPU资源的线程
setPriority

final方法,设置线程的优先级,1~10 1最低 10最高 5是默认值

线程的优先级具有继承性,比如A线程启动B线程,则A和B的线程优先级是一样的

getPriorityfinal方法,获取线程优先级
setDaemon设置守护线程(也叫服务线程,用于为系统中的对象和线程提供服务,如果都是服务线程,那么JVM结束,垃圾回收线程是守护线程)
isDaemon判断是否是守护线程
jointhread1.join();使当前线程进入阻塞状态,thread1线程执行完后,再唤醒当前线程
yeild使当前线程进入就绪状态
waitObject类的方法,让当前线程进入阻塞状态,并且释放它持有的同步锁
notifyObject类的方法,唤醒一个阻塞状态的线程
notifyAllObject类的方法,唤醒所有阻塞状态的线程

                                                                                                                                                                                                                                                                                        

join方法的使用

package com.cc.thread;public class ThreadJoin {public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread("线程1"){@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}};thread1.start();thread1.join();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}}

interrupt、interrupted和isInterrupted的作用和区别

  1. interrupt设置线程中断状态为true
  2. interrupted先返回当前线程中断状态,然后设置线程中断状态为false
  3. isInterrupted返回当前线程中断状态
  4. 下面的demo只用到了sleep方法,wait,join方法类似于sleep
package com.cc.thread;public class InterruptTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(){@Overridepublic void run() {for (int i = 0; i < 5; i++) {try {sleep(2000);//线程默认中断状态为false,调用sleep方法,或者在sleep的过程中,当中断状态为true时,执行sleep会抛出异常interrupt();//设置中断状态为true} catch (InterruptedException e) {//抛出异常后中断状态自动设置为falseSystem.out.println("出现中断异常,中断状态:"+isInterrupted());}System.out.println("正常执行,中断状态:"+isInterrupted());}}};thread.start();}}
package com.cc.thread;public class InterruptTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(){@Overridepublic void run() {for (int i = 0; i < 5; i++) {try {sleep(2000);//线程默认中断状态为false,调用sleep方法,或者在sleep的过程中,当中断状态为true时,执行sleep会抛出异常interrupt();//设置中断状态为trueSystem.out.println("interrupted方法:"+interrupted());//此函数首先返回当前的中断状态,然后将中断状态置为falseSystem.out.println("isInterrupted:"+isInterrupted());} catch (InterruptedException e) {//抛出异常后中断状态自动设置为falseSystem.out.println("出现中断异常,中断状态:"+isInterrupted());}System.out.println("正常执行,中断状态:"+isInterrupted());}}};thread.start();}}

wait方法的使用

package com.cc.thread;public class ObjectWait {public static void main(String[] args) {try {Thread threadTest = new Thread(){public void run(){System.out.println("执行线程中方法");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}};threadTest.start();synchronized(threadTest){threadTest.wait();		//当线程终止的时候,会调用线程自身的notifyAll()方法}System.out.println("执行到了这里");} catch (InterruptedException e) {e.printStackTrace();}}
}

synchronized

synchronized的用法参考Java中使用同步关键字synchronized需要注意的问题 - @ 小浩 - 博客园

synchronized是非公平锁

synchronized的实现原理参考Java中的锁——Lock和synchronized - 夏末秋涼 - 博客园

 1,synchronized代码块基于进入和退出monitor对象实现。代码编译后将monitorenter指令插入同步代码块的前面,monitorexit指令插入同步代码块的后面,发生异常时也会执行monitorexit指令

2,synchronized方法读取运行时常量池中方法的 ACC_SYNCHRONIZED 标志来隐式实现的

3,synchronized用的锁存储在对象头中的markword,markword中的锁标记指向的是monitor对象,

锁标记位(无锁01、轻量级锁00、重量级锁10、偏向锁01)

4,monitor对象有两个队列(EntryList、WaitSet)以及锁持有者Owner标记

线程安全的概念

什么是线程安全:在多线程环境下,线程安全的代码会通过线程同步机制保证各个线程可以正常的正确的执行,不会出现数据污染等意外情况。

什么是线程同步:是指各个线程按照一定的顺序执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/530419.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

配置JAVA开发环境

1、首先去Oracle官方网站下载所需版本的JDKhttp://java.sun.com/products/archive/&#xff0c;然后安装&#xff0c;其实只需要安装jdk就可以了&#xff0c;不需要安装jre 2、按照后配置环境变量JAVA_HOME 然后在path最前面添加%JAVA_HOME%\bin; 3、cmd中输入java -version,提…

【JAVA基础篇】枚举

/*** 一组相同类型的常量的集合* author cc**/ public class EnumDemo {public static void main(String[] args) {//遍历for(WorkDay workDay:WorkDay.values()){System.out.println("序号&#xff1a;"workDay.ordinal());//ordinal&#xff0c;返回枚举常量的序号…

【JAVA基础篇】集合框架

一、集合框架图 Java集合框架主要包含两种类型的容器&#xff0c;一是集合(Collection)&#xff0c;存储元素集合&#xff0c;二是图(Map)&#xff0c;存储键(key)-值(value)对.Collection接口下面有两个重要的子接口List和Set&#xff0c;再下面是一些抽象类&#xff0c;最后是…

【JAVA基础篇】对象初始化过程

我们都知道&#xff0c;创建对象是由 new关键字调用构造方法 返回类实例&#xff08;实际上还可以通过反射来创建实例&#xff09;。 例如 : Person jack new Person(); 这句话到底做了什么事情呢 &#xff1f; 其实就是讲对象的初始化过程。 1、 new 用到了Person.class,所…

【Java基础篇】try catch finally语句包含return语句时的执行过程

网上有很多人探讨Java中异常捕获机制try…catch…finally块中的finally语句是不是一定会被执行&#xff1f; 很多人都说不是&#xff0c;当然他们的回答是正确的&#xff0c;经过我试验&#xff0c;至少有两种情况下finally语句是不会被 try语句没有被执行到&#xff0c;如在…

eclipse指定JDK版本启动,解决version XXX of the JVM is not suitable for this product.Version:XXX 问题

问题描述&#xff1a;启动eclipse时&#xff0c;提示version 1.7.0 of the JVM is not suitable for this product.Version:1.8 or greater is required. 原因分析&#xff1a;原因是我的笔记本安装了多个JDK版本&#xff0c;但是现在我的JAVA_HOME配置的是jdk1.7的路径&#x…

【JAVA基础篇】Socket编程

一、Socket的概念 Socket是一种通讯机制&#xff0c;通常称为套接字。英文原意是插座&#xff0c;顾明思义&#xff0c;Socket像是一个多孔插座&#xff0c;可以提供多个端口的连接服务 ps:至于socket在计算机术语中怎么就翻译成了“套接字”这个令人费解的词&#xff0c;这真…

【JAVA基础篇】注解

一、什么是注解&#xff1f; 注解是元数据&#xff0c;所谓元数据就是描述数据的数据。 在annotation诞生之前&#xff08;jdk1.5诞生了注解&#xff09;&#xff0c;甚至之后&#xff0c;xml被广泛的由于描述元数据。但是后来&#xff0c;有一些应用开发工程师和架构师觉得它…

【JAVA基础篇】IO流

一、流的概念 “对语言设计人员来说&#xff0c;创建好的输入&#xff0f;输出系统是一项特别困难的任务。” ――《Think in Java》 无论是系统、还是语言的设计中IO的设计都是异常复杂的。面临的最大的挑战一般是如何覆盖所有可能的因素&#xff0c;我们不仅仅要考虑文件、…

SpringMVC注解

一&#xff0c;RequestMapping 可以用在类和方法上 1.1 作用&#xff1a; 将客户端请求映射到可匹配的类和方法中 1.2 属性&#xff1a; name 给映射指定一个名字 path(同value相同&#xff09; 请求的url&#xff0c;path{"/mixedAttribute1","/mixedA…

【JAVA基础篇】运算符

一、表达式 表达式由运算符和操作数组成 例如&#xff1a; 5 num1 num1num2 sumnum1num2 二、运算符分类 算数运算符、赋值运算符、关系运算符、逻辑运算符、条件运算符、位运算符 三、算数运算符 四、赋值运算符 格式&#xff1a;变量表达式 例如&#xff1a;int n3…

a4纸网页打印 table_打印模板不愁人,你还在打印单调的A4纸吗?

软件介绍早在几年前&#xff0c;社会上就已经开始了数字化、无纸化的推广&#xff0c;但是就算再怎么无纸化&#xff0c;纸张还是有它必要的存在&#xff0c;在工作、学习过程中&#xff0c;打印的需求也必不可少的。但是一般的打印都是比较平庸的&#xff0c;要做会议记录&…

IP地址、子网掩码、网关、默认网关、DNS的理解

IP地址 Internet上为了区分数以亿计的主机而给每个主机分配一个专门的地址&#xff0c;通过IP地址可以访问到每台主机。 子网掩码 子网掩码又称网络掩码、地址掩码、子网络遮罩。它是用来指明一个IP地址哪些位标识的是主机所在的子网&#xff0c;以及哪些位标识的是主机的位…

上证指数30年k线图_技术预判2020:上证指数要突破3500点才会“井喷”

2019年的行情很快就要收官了&#xff0c;截止目前&#xff0c;上证指数今年的涨幅是20.5%&#xff0c;不过可能有部分投资者今年的收益率还没达到大盘指数的平均水平。不管怎样&#xff0c;今年很快就要翻篇了&#xff0c;关键是看2020年股市能不能迎来更好的行情了。而总结得失…

【JAVA基础篇】基本数据类型及自动类型转换

一、8种基本数据类型以及占用内存空间大小 boolean 1byte或4byte byte 8bit/1byte char 16bit/2byte short 16bit/2byte float 32bit/4byte int 32bit/4byte long 64bit/8byte double 64bit/8byte 二、自动类型转换 …

的优缺点_浅谈桉木家具的优缺点

家具现在的材质是有很多的&#xff0c;木质的&#xff0c;石材的&#xff0c;还有真空充气的&#xff0c;都是很不错的类型。桉木家具是现在很多人都喜欢的一种材质&#xff0c;但是很多人对桉木家具的优缺点不是很清楚&#xff0c;为了能够让大家更加清楚的了解桉木家具&#…

【算法篇】递归

一、递归的概念 程序调用自身的编程技巧称为递归。 递归的核心思想就是将一个大规模复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。 二、递归的优点 使用递归的好处是只需要少量的代码就可以描述出求解问题过程中多次重复的计算&#xff0c;大大减少了程序…

客户说发货慢怎么回复_女生微信说身体不舒服怎么回复关心她?

当你不在女生身边&#xff0c;女生微信给你说身体不舒服&#xff0c;肯定需要说点话来安慰她了。多喝热水肯定是不行了&#xff0c;一点用处都没有&#xff0c;还会让女生觉得你根本不重视她&#xff0c;是在敷衍她&#xff0c;那女生微信说身体不舒服怎么回复关心她呢&#xf…

【算法篇】八种内排序算法

常用的八种内排序算法分别是&#xff1a; 交换排序&#xff1a;冒泡排序、快速排序选择排序&#xff1a;简单选择排序、堆排序插入排序&#xff1a;直接插入排序、希尔排序归并排序基数排序 内排序巧记&#xff1a;选(选择)舰(简单选择)队(堆)的时候脚(交换)毛(冒泡)快(快速)&…

数据分析专题报告范文6篇_小学生看图写话范文:小熊玩跷跷板?(6篇),让孩子参考练习...

​范文01&#xff1a;小熊跷跷板一天&#xff0c;天气晴朗&#xff0c;胖乎乎的小熊和小白兔一起玩跷跷板。小熊一屁股坐在地上&#xff0c;小白兔说&#xff1a;“啊&#xff01;我有恐高症哇&#xff01;”小熊说&#xff1a;“我比你重&#xff0c;所以你没有办法把我翘起来…