进程-线程

进程Process,处于运行中的程序,系统进行资源分配和调度的独立单位,拥有独立的内存空间(堆)。

  • 动态性:生命周期和状态;
  • 独立性:独立实体;
  • 并发性:Concurrency,抢占式多任务操作策略;

注:并发性是同一时刻只有一条指令执行,但是CPU是在多进程间快速切换;并行性,parallel,是同一时刻有多条指令在多个处理器上同时执行。

线程Thread,(轻量级进程,LightWeight Process),线程是进程的执行单元,在进程(程序)中是独立的、并发的执行流。线程是抢占式执行的,一个线程可以创建和撤销另一个线程。

线程是进程的组成部分,线程的调度和管理由进程负责。一个线程必须有一个父进程,一个进程可以拥有多个线程,多个线程共享进程的全部(系统)资源、进程代码段等,但是线程有独立的堆栈、寄存器集合、局部变量、程序计数器等,不同线程之间相互独立。线程在进程(程序)中的地位,等同于进程在操作系统中的地位。

操作系统可以执行多个任务(进程),进程可以并发处理多个任务(线程)。

多线程,隔离程度小、并发性能好。

  • 进程创建代价大;
  • 线程共享进程内存空间;

参见:线程总结


创建线程

继承java.lang.Thread类,重写run()方法

public class Thread implements Runnable {
private Runnable target;
public Thread() {}
public synchronized void start() {}
@Override
public void run() {}
private void exit() {}
public final native boolean isAlive();
}

 特点

  • 简单易实现,利用this直接获取当前线程;
  • 线程类已经继承了Thread类,不能再继承其他类;
  • 线程类的多个线程无法共享线程类的实例变量;

 步骤

  • 定义Thread类的派生类,重写Thread类的run()方法;
  • 创建Thread派生类的实例(线程对象);
  • 调用线程对象的start()方法,启动线程;
public class MyThread extends Thread
{
public void run(){
// 线程执行体
System.out.println( getName() + ":" + getId() );
}
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
MyThread myThread = new MyThread();
myThread.start();
}
}

实现java.lang.Runnable接口,实现run()方法

@FunctionalInterface
public interface Runnable {
public abstract void run();
}   

 特点

  • 实现较复杂,必须利用Thread.currentThread()方法访问当前线程;
  • 线程类只是实现了Runnable/Callable接口,还可以继承其他类,避免Java单继承的限制;
  • 线程类的多个线程可以共享同一个target对象(共享线程类[实际上应该是线程的target类]的实例变量);
  • 代码可以被多个线程共享,代码和数据独立,适合多个相同线程访问同一资源;
  • Runnable接口是函数式接口,可以利用Lambda表达式创建Runnable对象;

步骤

  • 定义Runnable接口的实现类,实现Runnable接口的run()方法;
  • 创建Runnable接口实现类的实例,并以此实例作为Thread的target来创建Thread对象;
  • 调用线程对象的start()方法,启动线程;
public class MyRunnable implements Runnable
{
public void run(){
// 线程执行体
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
MyRunnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable, "sqh-Runnable");
myThread.start();
}
} 

实现java.lang.Callable接口,结合Future和线程池

 特点

  • 同Runnable;
  • Callable接口是函数式接口,可以利用Lambda表达式创建Callable对象;

 步骤

  • 定义Callable接口的实现类,实现Callable接口的call()方法;
  • 创建Callable接口实现类的实例,并用FutureTask类封装Callable对象;
  • 利用FutureTask对象作为Thread对象的target创建线程Thread对象,并调用线程对象的start()方法,启动线程;
  • 通过FutureTask对象的get()方法获取call()方法的返回值;

其中,call()方法可以有返回值,可以声明抛出异常。

public class MyCallable implements Callable<String>
{
public String call() throws Exception {
// 线程执行体
return Thread.currentThread().getName();
}
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
MyCallable myCallable = new MyCallable();
FutureTask<String> ft = new FutureTask<String>(myCallable);
Thread myThread = new Thread(ft, "sqh-Callable").start(); try{
System.out.println(ft.get());
}
catch(Exception e){
e.printStackTrace();
}
}
}  

线程状态

  • 新生状态(New)
  • 就绪状态(Runnable)
  • 运行状态(Running)
  • 阻塞状态(Blocked)
  • 死亡状态(Dead)

每个 Java 对象都有一个(内置的)锁对象,而且只有一把钥匙。创建锁对象:

  • this 关键字
  • 类名.class
  • 对象.getClass()

注意以下几个小知识点

  • 线程进入 Sleep() 睡眠状态时,线程仍然持有锁、不会释放
  • 同步方法会影响性能(死锁),优先考虑同步代码块

死锁

当多个线程完成某个功能需要同时获取多个共享资源的时候可能会导致死锁

两个任务以相反的顺序申请两个锁:线程T1获得锁L1,线程T2获得锁L2,然后T1申请获得锁L2,同时T2申请获得锁L1。

避免死锁

线程通信

等待唤醒机制:Java 通过 Object 类的 wait,notify,notifyAll 方法实现线程间通信

  • wait:告诉当前线程放弃执行权,并放弃锁、进入阻塞状态,直到其他线程获得执行权,并持有相同的锁、调用notify为止
  • notify:唤醒持有同一个锁的调用了 wait 的第一个线程,该线程进入可运行状态、等待获取执行权
  • notifyAll:唤醒持有同一个锁的调用了 wait 的所有的线程

其中,操作线程的等待和唤醒必须是针对同一个锁对象(锁可以是任一对象,Object 类)。

注意,sleep() 和 wait() 方法的区别

  • sleep():释放资源,不释放锁,Thread的方法
  • wait(): 释放资源,释放锁,Object的方法

线程间通信,其实就是多个线程在操作同一个资源,但操作动作不同。

关于线程的 join() 方法

join 可以用来临时加入线程执行:当A线程执行到了B线程join方法时,A就会等待,直到B线程都执行完、A才会执行。

Java - 多线程与锁的更多相关文章

  1. JAVA多线程与锁机制

    JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...

  2. Java 多线程:锁(一)

    Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ...

  3. Java 多线程:锁(二)

    Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ...

  4. Java 多线程:锁(三)

    Java 多线程:锁(三) 作者:Grey 原文地址: 博客园:Java 多线程:锁(三) CSDN:Java 多线程:锁(三) StampedLock StampedLock其实是对读写锁的一种改进 ...

  5. java多线程----悲观锁与乐观锁

    java多线程中悲观锁与乐观锁思想 一.悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线 ...

  6. (转)java 多线程 对象锁&类锁

    转自:http://blog.csdn.net/u013142781/article/details/51697672 最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不 ...

  7. java多线程之锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

    转载至:https://blog.csdn.net/zqz_zqz/article/details/70233767 之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比 ...

  8. Java多线程--公平锁与非公平锁

    上一篇文章介绍了AQS的基本原理,它其实就是一个并发包的基础组件,用来实现各种锁,各种同步组件的.它包含了state变量.加锁线程.等待队列等并发中的核心组件,现在我们来看一下多线程获取锁的顺序问题. ...

  9. java多线程编程——锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  10. Java多线程之锁优化策略

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html  锁的优化策略 编码过程中可采取的锁优化的思路有以下几种: 1:减少锁持有时间 例如:对 ...

随机推荐

  1. AlienWare

    https://www.chiphell.com/thread-1705089-1-1.html AlienWare

  2. ubuntu18 tensorflow cpu fast_rcnn

    (flappbird) luo@luo-All-Series:~/MyFile/TensorflowProject/tf-faster-rcnn/lib$ makepython setup.py bu ...

  3. opennebula 添加kvm主机日志

    Sun Sep :: [ReM][D]: Req: UID: HostDelete invoked, Sun Sep :: [ReM][D]: Req: UID: HostDelete result ...

  4. UML建模之类图

    UML类间关系的种类 从一个示例开始 请看以下这个类图,类之间的关系是我们需要关注的: 车的类图结构为<<abstract>>,表示车是一个抽象类: 它有两个继承类:小汽车和自 ...

  5. C# 基础连接已经关闭: 发送时发生错误

    在程序中获取某个https网址的源码,GetRespose()时 出现了“基础连接已经关闭: 发送时发生错误.”的错误提示. 翻了论坛后,有个仁兄说:                 //.net 4 ...

  6. layer + ajax 弹出框

    项目中用到的一个很友好的弹出提示窗口.结合ajax很丝滑的与后台交互数据.引入layer.min.js layer.msg('你确定删除么?', { time: 0 //不自动关闭 ,btn: ['确 ...

  7. elasticsearch-jdbc 使用

    elasticsearch-jdbc是一个将关系型数据库(RDBMS)数据导入到ElasticSearch库中的一个工具包,支持mysql.oracle.postgrey.csv等存储列式数据的容器. ...

  8. springboot+swagger集成

    一.swagger介绍 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger的方法和一些常见问题.如果想深入分析项目源码,了解更多内容 ...

  9. Windows 配置 nginx php 多版本切换

    1. 下载 nginx   nginx.org 2. 下载 php  windows.php.net   选择 nts 版本,解压后,将php.ini.development 重命名为  php.in ...

  10. vCenter Server Heartbeat

    1.简介 vCenter Server Heartbeat为VMware vCenter Server提供关键任务高可用性,保护虚拟基础架构免受硬件.网络.配置等的影响,基于Windows的服务,可为 ...