java基础篇笔记16

并发:指两个或多个时间在同一时间段内发生。
并行:指两个或多个时间在同一时刻发生(同时发生)。

进程:是指一个内存中运行的应用程序(进入到内存中的程序称为进程),每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。

多线程的好处:
1 效率高;
2 线程之间互不影响

主线程:执行主方法(main)的线程
单线程程序:执行从main方法开始,从上到下依次执行

多线程
多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。
当执行线程的任务结束了,线程自动在栈内存中释放了。但是当所有的执行线程都结束了,那么进程就结束了。

java.lang.Thread 类

常用方法:
public String getName() :获取当前线程名称。
线程的名称:
主线程:main
新线程:Thread-0, Thread-1, Thread-2
链式实现:Thread.currrentThread( ).getName( )
public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。
public void run() :此线程要执行的任务在此处定义代码。
public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
public static Thread currentThread() :返回对当前正在执行的线程对象的引用。

创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类重写 Thread 类的 run 方法。接下来可以分配并启动该子类。
实现步骤:
1 创建一个Thread类的子类;
2 在Thread类的子类中重写run方法,设置线程任务;
3 创建Thread类的子类对象;
4 调用Thread类中的方法start方法,开启新的线程,执行run方法

创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后重写 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。
实现步骤:
1 创建一个Runnable接口的实现类
2 在实现类中重写Runnable 接口的run 方法,设置线程任务
3 创建一个Runnable 接口的实现类对象
4 创建Thread 类的对象,构造方法中传递Runnable 接口的实现类对象
5 调用Thread 类中的start方法,开启新线程run方法

实现Runnable接口创建新线程程序的好处:
1 避免了单继承的局限性
一个类只能继承一个一个类(只能有一个父类),类继承了Thread 类就不能继承其他类
实现了Runnable 接口,还可以继承其他类,实现其他接口。
2 增强了程序的扩展性,降低了程序的耦合性
实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦)
实现类中,重写了run方法,用来设置线程任务
创建Thread 类对象,调用start方法,用来开启新线程

匿名内部类实现线程的创建
匿名:没有名字; 内部类:卸载其它类内部的类
匿名内部类作用:简化代码
把子类继承父类,重写父类方法,创建子类对象合成一步完成
把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成
匿名内部类的最终产物:子类/实现类对象,而这个类没有名字

格式:
new 父类/接口(){
重复父类/接口中的方法
};

线程安全:多线程访问共享数据,会产生线程安全问题。
单线程程序是不会出现线程安全问题的。
多线程程序,没有访问共享数据,也不会产生线程安全问题。

注意:线程安全问题是不能产生的。为了达到这个目的,我们可以让一个线程在访问共享数据时,无论是否失去了CPU的海行权,让其他的线程都只能等待,等待当前线程执行完线程任务,再让其他线程执行。

解决上述多线程并发访问一个资源的安全性问题,Java中提供了同步机制(synchronized)来解决。
有三种方式完成同步操作:

  1. 同步代码块。
  2. 同步方法。
  3. 锁机制。

同步代码块: synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

同步锁:
对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁.

  1. 锁对象 可以是任意类型。
  2. 多个线程对象 要使用同一把锁。
    3 锁对象的作用:
    把同步代码块锁住,只让一个线程在同步代码块中执行。
    注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着(BLOCKED)。

格式:
synchronized(锁对象){
可能会出现线程安全的代码(访问了共享数据的代码)
}

同步技术的原理:
使用了一个锁对象,这个所对象叫同步锁,也叫对象监视器
线程t1抢夺CPU的执行权,一个线程得到执行权后,执行run方法,遇到synchronized代码块,这个就会检查该synchronized是否有锁对象,发现有所对象,就进入同步执行
其他线程t2抢到执行权后,执行run方法,遇到synchronized,检查是否有锁对象
发现没有,就会进入到阻塞状态,一直等待前一个线程t1归还锁对象。
直到前一个线程t1执行完同步代码块中的代码,把锁对象归还给synchronized代码块,t2才能获取锁对象进入到同步中执行。

总结:同步中的线程,没有执行完毕不会释放锁,同步外的线程没有锁进不去同步。

同步保证了只能有一个线程在同步中执行共享资源,保障了安全。
但程序频繁的判断锁,释放锁,程序的效率会降低。

同步方法:使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外
等着。
使用步骤:
1 把访问了共享数据的代码抽取出来,放到一个方法中
2 在方法上添加synchronized修饰符
格式:(定义方法的格式)
修饰符 synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全的代码(访问了共享数据的代码)
}

定义一个同步方法,会把方法内部的代码锁住,只让一个线程执行
同步方法的锁对象是谁?
就是实现类对象 new RunableImpl( )
也就是this

静态的同步方法,锁对象是谁?
不能是this,this是创建对象之后产生的,而静态方法优先于对象
静态方法的锁对象是本类的class属性---->class文件对象(反射)

lock锁
java.util.concurrent.locks.Lock 接口提供了比synchronized代码块和synchronized方法更广泛的锁定操作。
Lock锁也称同步锁,加锁与释放锁方法化了,如下:
public void lock() :加同步锁。
public void unlock() :释放同步锁

使用步骤:
1 在成员为之创建一个Reentrantlock对象;
2 在可能会出现安全问题的代码前调用lock接口中的方法lock获取锁
3 在可能会出现安全问题的代码后调用lock接口中的方法unlock释放锁(可以将释放锁的命令放在finally代码块找中,无论程序是否异常,都要释放锁)

线程的状态
java.lang.Thread.State 之中列举了线程的六种状态
线程状态 导致状态发生条件
NEW(新建) 线程刚被创建,但是并未启动。还没调用start方法。
Runnable(可运行) 线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操
作系统处理器。
Blocked(锁阻塞) 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状
态;当该线程持有锁时,该线程将变成Runnable状态。
Waiting(无限等待) 一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入Waiting状态。进入这个
状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyAll方法才能够唤醒。
TimedWaiting 同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一状态
(计时等待) 将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep 、
Object.wait。
Teminated 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。
(被终止)

NEW:至今尚未启动的线程;
Runnable:正在java虚拟机中执行的线程;
Blocked:受阻塞并等待某个监视器锁的线程;
Waiting:无限的等待另一个线程来执行某一特定操作的线程;
TimedWaiting:等待另一个线程来执行取决于指定等待时间操作的线程;
Teminated:已退出的线程。

注意:
阻塞状态:具有CPU的执行资格,等待CPU空闲时执行;
休眠状态:放弃CPU的执行资格,CPU空闲也不执行。

线程进入到TimedWaiting有两种方式:
1 使用sleep(long m)方法,在毫秒值结束之后进入到Runnable状态。
2 使用wait(long m)方法,外套方法如果在毫秒值结束之后还没有被notify唤醒,就会自动醒来。

唤醒的方法:
void notify( ) 唤醒在此对象监视器上等待的单个线程。
void notifyAll( ) 唤醒在此对象监视器上等待的所有线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值