线程方法

摘要:
----------------------------------------------------------------------------------开启线程方式一:继承Thread类自定义类MyThread继承Thread类。只要有任何非后台线程还在运行,程序就不会结束。===================================================================同步线程线程安全问题:在多线程环境下,存在多条线程使用多条原子性语句对共享数据做了写操作解决办法:1、同步代码块2、同步方法3、Lock锁同步代码块格式:synchronized(对象
使用多线程原因:
1、当执行某个耗时任务时,需要开启多线程
2、希望多个任务“同时”执行
3、防止线程阻塞
4、完成某个特定的任务
进程:正在执行的程序

线程:具有完成特定任务的一条执行路径,是CPU执行的最小单位(数据传输的基本单位是字节)

注意:CPU在某个时间刻度上只能够执行一条原子性语句(字节最小是bit位)

原子性语句:不可再分割的语句
CPU执行原理
1、真实环境下,除了多核处理器,本质都是CPU在某一个时间点上执行了一条线程
2、CPU看起来像是同时执行,但是本质上只执行了一条线程的一条原子性语句
3、在Java的线程程序中,采用的是抢占式调度模式
4、并发和并行的区别:
并发:在同一个时间段同时执行
并行:在同一个时间刻度上同时执行,物理上同时执行
5、同步和异步的区别:
同步:本质就是串行执行,并发情况下会出现同步问题
异步:能够在处理一个任务的同时还能够处理其他事情
多进程的好处:提高了进程的使用率,从而间接提高了CPU的使用率
多线程的好处:提高了CPU的使用率
一个Java进程至少包含了2个线程:主线程、垃圾回收线程。

----------------------------------------------------------------------------------
开启线程方式一:
继承Thread类
自定义类MyThread继承Thread类。
MyThread类里面重写run( )方法。
创建线程对象
启动线程
注意:
1、启动线程使用的是start( )方法,而不是run()方法
2、线程不能多次启动,否则会报异常
显示线程的名称:
Thread.currentThread( )表示当前正在执行的是哪一条线程那么就是对应的那个线程的名称
Thread.currentThread( ).getName( ) 获取当前正在执行的线程的名称
run( )线程的核心任务代码区,类似于main方法
继承Thread的优点:能够直接在子线程访问Thread类的方式(优先访问继承Thread类)
-----------------------------------------------------------------------------------
开启线程的方式二(开发中建议使用):
1、自定义类MyRunnable实现Runnable接口
2、重写run()方法
3、创建MyRunnable类的对象
4、创建Thread类的对象,并把步骤3创建的对象作为构造参数传递
5、启动线程
Runnable方式开启线程的好处:
1、可以避免Java单继承带来的局限性
2、适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码、数据有效分离,较好的体现了面向对象的设计思想
--------------------------------------------------------------------------------------------
开启线程方式三:实现Callable方式开启线程(本质还是方式二,需要依赖一个类FutureTask )
public class FutureTask<V> implements RunnableFuture<V> { }
public interface RunnableFuture<V> extends Runnable, Future<V> { void run( ); }
public interface Callable<V> { V call() throws Exception; }
方式三开启线程的优点:
1、call方法有返回值,run方法没有返回值,可以返回结果给主线程
2、call方法可以抛出异常告知主线程(线程通信)
缺点:会导致主线程在计算完成之前阻塞
------------------------------------------------------------------------------------------------
开启线程方式四:本质是一个继承或者实现了某个类或者接口的子类匿名对象(在Android使用频繁)
注意:如果同时使用两种方式开启线程,继承Thread方式优先!!!
匿名内部类开启线程的好处:线程任务执行完毕就是垃圾对象,等待垃圾回收器空闲的时候回收,节约内存资源
----------------------------------------------------------------------------------------------------
Lambda表达方式开启线程
new Thread( ()->{
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
} ).start();
函数式接口:只有一个抽象方法的接口称为函数式接口(Runnable)
------------------------------------------------------------------------------------------------------
设置和获取线程的名称
通过构造方法
Thread(String name) 分配新的 Thread 对象。
Thread(Runnable target, String name) 分配新的 Thread 对象。
通过线程的成员方法
public final String getName( )
public final void setName(String name)
通过静态方法
public static Thread currentThread( ) 可以获取任意方法所在的线程名称
可以获取主线程的线程名称:Thread.currentThread( ).getName( ) ;
获取线程的id: long getId( )
设置和获取线程的优先级
public final int getPriority( )
public final void setPriority(int newPriority)
优先级1~5~10
线程休眠:Thread.sleep(1000L) 阻塞当前正在执行的线程1s
线程中断:public final void stop()终止子线程的生命周期(已停用)

public void interrupt()给子线程抛出一个异常,子线程还可以继续执行
后台线程:在程序运行的时候在后台提供的一种通用的服务的线程,并且这种线程并不属于程序中不可或缺的部分。
只要有任何非后台线程还在运行,程序就不会结束。
线程加入:public final void join( )(t.join();//主要用于等待t线程运行结束)
线程礼让:public static void yield( )让出CPU执行权一小会,一小会不确定多久
让出了CPU的执行权,释放了执行权,但还可以争夺。
===================================================================
同步线程
线程安全问题:在多线程环境下,存在多条线程使用多条原子性语句对共享数据做了写操作
解决办法:1、同步代码块 2、同步方法 3、Lock锁
同步代码块
格式:
synchronized(对象){需要同步的代码;}
同步的好处:
解决了多线程的安全问题
同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,
降低了程序的运行效率。如果出现了同步嵌套,就容易产生死锁问题

锁对象:
锁对象必须是多个线程同一把锁
锁对象可以是任意对象
同步方法:
格式:
public synchronized 返回值 方法名(参数列表){需要同步的代码块}

如果锁对象是this,就可以考虑使用同步方法。
方法分为两种:静态方法和非静态方法
非静态方法的锁对象:this
静态方法的锁对象:类的字节码文件对象
注意:synchronized可以修饰方法,修饰代码块,但是不能修饰构造方法、成员变量等。
Lock锁出现死锁现象
死锁指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象。
锁对象是任意对象,如果设计在Thread里面,那就定死了,所以和锁有关的方法设计在Object类中
线程池的作用:能提高线程的效率,一般创建线程消耗时间较长,防止频繁创建而浪费时间

线程池里的每一个线程代码结束后并不会死亡,而是再次回到线程池中称为空闲状态,等待下一个对象来调用。
线程池的开启

Executors工厂类来生产线程池
调用构造方法:public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor( )
-------------------------------------------------------------------------------------------------------------
线程的开启方式七:定时器
特点:可以在指定的时间执行指定的任务,同时还可以延时执行或者反复执行
定时器类:Timer
定时任务类:TimerTask
void schedule(TimerTask task, Date time)在指定的时间执行某个任务
void schedule(TimerTask task, Date firstTime, long period)在指定的时间执行指定的任务
void schedule(TimeTask task, long delay)延时多长时间执行指定的任务
void schedule(TimeTask task, long delay, long period)延迟多长时间执行指定的任务到多长周期

免责声明:文章转载自《线程方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇可视化日历(2)Android研究Android系统初始化程序init和初始化配置文件init.rc分析[zz]下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WinForm 进程、线程

一、进程 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。 它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。 Process 类,用来操作进程。 命名空间:using System.Diagnostics; Process.Start("calc");   //打开计算器Process.Start("mspaint");   /...

创建线程是否调用CloseHandle

关于是否在创建线程后调用Closehandle一直困惑,今天查了查,才明白。 CloseHandle关闭句柄并没有终止新创建的线程。只是表示对新创建的线程的引用不敢兴趣,系统会递减新线程的线程内核对象的使用计数。当使用计数为0的时候,系统就会释放线程内核对象。如果在主线程中没有关闭线程的句柄,始终都会保留一个引用。这样线程内核对象的引用计数就不会为0。即使...

Java常用类库与技巧

Java异常 异常处理机制主要回答了三个问题 What:异常类型回答了什么被抛出 Where:异常堆栈跟踪回答了在哪抛出 Why:异常信息回答了为什么被抛出 Java的异常体系 ​ Error和Exception的区别 从概念角度解析Java的异常处理机制: 1.Error:程序无法处理的系统处理,编辑器不做检查(如系统崩溃,虚拟机错误,内存空间不足,方法...

boost之ThreadPool

threadpool是基于boost库实现的一个线程池子库,但线程池实现起来不是很复杂。我们从threadpool中又能学到什么东西呢? 它是基于boost库实现的,如果大家对boost库有兴趣,看看一个简单的实现还是可以学到点东西的。 threadpool基本功能 1、任务封装,包括普通任务(task_func)和优先级任务(prio_task_fun...

Unity C#笔记 协程详解(转)

目录 什么是协程 多线程 协程 协程的使用场景 协程使用示例 Invoke的缺陷 协程语法 开启协程 终止协程 挂起 协程的执行原理 什么是协程 在Unity中,协程(Coroutines)的形式是我最喜欢的功能之一,我都会使用它来控制需要定时的。 协同程序,在主程序运行的同时,开启另外一段逻辑处理,来协同当前程序的执行。 可能看了...

Java 8 (10) CompletableFuture:组合式异步编程

https://www.cnblogs.com/baidawei/p/9447737.html   随着多核处理器的出现,提升应用程序的处理速度最有效的方式就是可以编写出发挥多核能力的软件,我们已经可以通过切分大型的任务,让每个子任务并行运行,使用线程的方式,分支/合并框架(java 7) 和并行流(java 8)来实现。 现在很多大型的互联网公司都对外...