多线程

来源:互联网 发布:尿白蛋白肌酐比值算法 编辑:程序博客网 时间:2024/05/17 08:50

Thread

进程是一个正在执行中的程序,每一个进程都有一个执行顺序,该顺序是一个执行路径或叫执行单元

线程是进程中的一个独立的控制单元,在控制着进程的执行

Java vm启动的时候会有一个进程java.exe,该进程中有一个线程负责java程序的执行,而且这个线程运行的代码存在于main方法中(主线程),还有一个负责垃圾回收机制的线程。

方法一步骤:定义类继承Thread,覆写Thread类中run方法(封装线程要运行的代码),调用start方法(启动线程,执行该线程run方法)

方法二步骤:定义类实现Runnable接口,覆盖Runnable接口中的run方法,通过Thread类建立线程对象,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数(自定义的run方法所属对象是Runnable接口的子类对象,所以要让线程去执行指定对象的Runnable方法,就必须明确该run方法所属对象),调用Thread类的start方法开启线程并调用Runnable接口子类的run方法

多线程安全问题

问题原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程就参与进来执行,导致共享数据的错误。

解决办法:对多条操作共享数据的语句,只能让一个线程在某一个时间段都执行完,在执行过程中其他线程不可以参与执行。

Java对于多线程的安全问题提供了专业的解决方式,就是同步代码块

synchronized(对象){

需要被同步的代码

}

这里的对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁;火车上的卫生间--例子

**同步的前提

1,必须要有两个或两个以上的线程

2,必须是多个线程使用同一个锁

2,必须保证同步中只能有一个线程在运行

好处:解决了多线程的安全问题

弊端:多个线程需要判断锁,较为消耗资源

同步代码块封装代码带着同步的特性,如果让函数带着同步性,即-->同步函数

函数需要被对象调用,那么函数都有一个所属对象引用,同步函数使用的锁是this

如果同步函数被静态修饰后,使用的不再是this,因为静态方法中也不可能定义this。静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,类名.class,该对象的类型是Class.,即静态的同步方法使用的锁是该方法所在类的字节码对象

**死锁

-->你持有一个锁,我也有一个锁,我不放我的锁要到你那里运行,你也不放你的锁要到我这里运行,谁都不放,就会导致程序挂在那不动了

即:死锁现象是同步里面嵌套着同步,而使用的锁却不同

线程间通信

-->多个线程在操作同一个资源,但操作的动作不同

wait(),notify(),notifyAll():

1,这些方法存在于同步中,因为要对持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁

2,使用这些方法必须要标识所属的同步的锁,只有同一个锁上的被等待线程,才可以被同一锁上的notify()唤醒,即wait()和notify()必须是同一个锁

3,锁可以是任意对象,所以任意对象调用的方法一定定义在Object类中

wait()释放资源,也释放锁;sleep()释放资源,但不释放锁


当出现生产者与消费者关系时,要用while(flag)循环判断标记,并notifyAll()唤醒所有线程

定义while判断标记,让被唤醒的线程再一次判断标记;只使用notify,容易出现只唤醒本方线程的情况导致程序中的所有线程都等待

JDK1.5中提供了多线程升级解决方案:

显式的锁机制,以及显式的锁上的等待唤醒操作机制,同时把等待唤醒机制封装,一个锁可以对应多个Condition.

Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。 

停止线程:

stop方法已经过时,如何停止线程,只有让run方法结束,开启多线程运行,运行代码通常是循环结构,只要控制循环,就可以让run方法结束。

当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。当没有指定方式让冻结的线程恢复到运行状态,这时需要对冻结状态清除interrupt();,强制让线程恢复到运行状态来,这样就可以操作标记让线程结束。

守护线程:setdaemon()在启动线程时调用

Join方法:要CPU执行权,当A线程执行到了B线程的join()方法时,那么A线程就会等B线程都执行完,A才会执行,join用来临时加入线程执行。

优先级&yield方法:toString()返回该线程的字符串表示形式,包含线程名称、优先级、线程组;

默认优先级为5 setPriority(int newPriority)MAX_PRIORTY(10)、MIN_PRIORITY(1)、NORM_PRIORITY(5)

yield()暂停当前正在执行的线程对象,执行其他线程对象

原创粉丝点击