java 多线程笔记

一、先简单粗暴解释一下一些与线程有关的概念

  1.并行与并发

   并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。

   并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。

  2.资源共享

   多个线程调用资源,是同一个或多个资源。

  3.线程安全

   在并发的情况之下,代码经过多线程使用,线程的调度顺序不影响最后结果,则是线程安全的。

  3.同步

    Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全。例如使用@synchronized。

  Java线程具有五中基本状态

  新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

  就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待    CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

  运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入    口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

  阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次   被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

   1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

   2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

   3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕    时,线程重新转入就绪状态。

  死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期   

二、实现Runnable接口相比继承Thread类有以下好处:

1.避免单继承的局限,一个类可以实现多个接口

2.适合资源的共享。

通过例子说明资源共享:

  Runnable接口:

  

  测试:

  

  结果:明显Runnable可以实现资源共享

  

Thread父类:

  

  测试:

  

  结果:没有实现资源共享

  

总结: 

(资源共享)

  java多线程访问共享资源的方式:

    (1).如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据。

    (2).如果每个线程执行的代码不同,这时候需要使用不用的Runnable对象,这种情况有两种方式实现:

    1.将共享资源封装在另一个对象中,然后将这个对象逐一传给各个Runnable对象(在java中,对象(同过new来生成的对象)作为参        数传递时,传递的是对象的地址),每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据        进行各个操作的互斥和通信。

    2.将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作也分配给外        部类,以便实现对共享数据进行各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法。

      总之,要同步互斥的几段代码最好放在几个独立的方法中,这些方法再放在一个类中,这样比较容易实现他们之间的互斥和通        信。

(3).简单极端的方式,在任意一个类中定义一个static变量,static变量将被所有线程共享

(同步)。同步方法/同步代码块

    注:同步是一种高开销的操作,因此应该尽量减少同步的内容。

   通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

  

时间: 2024-11-05 18:38:37

java 多线程笔记的相关文章

Java多线程笔记

1.并发通常可以提高单处理器上程序的性能 其实,在单处理器上并发的执行程序锁用的开销大于顺序执行.然而顺序执行时,程序有时会因为某些条件(通常是I/O问题)导致不能继续执行,称为线程阻塞,如果没有并发,程序将停止不前.而使用了并发,一个任务阻塞,其他任务还可以继续执行,这就保证了程序的完成.所以,如果确定没有任务会出现阻塞,在单处理器上并发执行程序是不必要的. 2.并发在单处理器上性能提高最常见的实例是--事件驱动的编程 并发最吸引人的额就是可以产生可响应的用户界面,比如某个程序将长期的运行某个

java多线程笔记(二)

      java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Semaphore.   线程同步问题引入:       创建一个银行账户Account类,在创建并启动100个线程往同一个Account类实例里面添加一块钱.在没有使用上面三种方法的情况下: 代码: import java.util.concurrent.ExecutorService; import

java多线程笔记 目录

两个重要的概念(进程和线程) 进程(官方):计算机中程序关于某数据集合的一次运行活动,是计算机系统进行资源分配和调度的基本单位,是操作系统结构的基础. 线程(官方):线程是进程的实例,是CPU进行资源分配和调度的最小单位,线程是轻量级的进程. This is an example inline link. 原文地址:https://www.cnblogs.com/lizhouwei/p/9059274.html

Java多线程技术学习笔记(二)

目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和wait的区别 停止线程的方式 守护线程 线程的其他知识点 一.线程间的通信示例 返目录回 多个线程在处理同一资源,任务却不同. 假设有一堆货物,有一辆车把这批货物往仓库里面运,另外一辆车把前一辆车运进仓库的货物往外面运.这里货物就是同一资源,但是两辆车的任务却不同,一个是往里运,一个是往外运. 下面

Java多线程学习笔记--生产消费者模式

实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前水平只能膜拜,本次只能算学习笔记,为了巩固自己对Java多线程常规知识点的理解,路过大神还望能指导指导.下面一段代码是最常规的生产者消费者的例子: package com.zhanglei.demo; import java.util.ArrayList; import java.util.List

Java多线程(全)学习笔记(下)

七.Callable和Future接口 C#可以把任意方法包装成线程执行体,包括那些有返回值的方法.Java也从jdk1.5开始,加入了Callable接口用来扩展Runnable接口的功能,Callable接口提供一个call()来增强Runnable的run().因为call()可以有返回值,可以声明抛出异常. 但是Callable是新增的接口 并没有继承Runnable接口,那么肯定不能作为Runnable target来直接作为Thread构造方法的参数.必须由一个中间的类来包装Call

Java多线程编程(学习笔记)

一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过多线程的使用,可以编写出非常高效的程序.但如果创建了太多的线程,程序执行的效率反而会降低. 同时上下文的切换开销也很重要,如果创建太多的线程,CPU花费在上下文的切换时间将对于执行程序的时间. 二.Java多线程编程 概念 在学习多线程时,我们应该首先明白另外一个概念. 进程:是计算机中的程序关于某

JAVA学习笔记 -- 多线程之共享资源

在多线程程序运行过程中,可能会涉及到两个或者多个线程试图同时访问同一个资源.为了防止这种情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其它线程的访问.而这种机制也常常被称为互斥量,本文主要介绍它的两种方式synchronized和Lock . 1.synchronized 当任务要执行被synchronized关键字保护的代码片段的时候,它会检查锁是否可用,然后获取锁,执行代码,释放锁.synchronized也有两种用法: A.synchronized方法 import

Java多线程学习笔记(一)

一 概述 一个进程只有一个至少会运行一个线程,Java中同样存在这样,在调用main方法的时候,线程又JVM所创建. 1 package link.summer7c.test; 2 3 public class Test{ 4 public static void main(String[] args){ 5 System.out.println(Thread.currentThread().getName()); 6 } 7 } 运行结果:main 叫做main的线程正在执行main()方法中