多线程基础阶段

多线程

多线程五个状态

1,new 新生状态

2,start 就绪状态

3,CPU 就绪状态

4,干涉 死亡状态

5,阻塞 阻塞状态

package cn.si.cop;

/**

* 终止线程两种方式

* 线程正常执行完毕

* 外部

*/

public class TerminateThread implements Runnable {

private boolean flag=true;

private String name;

public TerminateThread(String name){

this.name=name;

}

@Override

public void run() {

int i=0;

while(flag){

System.out.println(name+"-->"+i++);

}

}

private void terminate(){

this.flag=flag;

}

public static void main(String[] args) {

TerminateThread tt=new TerminateThread("C罗");

new Thread(tt).start();

for ( int i=0;i<99;i++){

if (i==88){

tt.terminate();//线程终止

System.out.println("tt game over ");

}

System.out.println("main-->"+i);

}

}

}

线程状态。线程可以处于一下状态之一

new

尚未启动的线程处于此状态

RUNNABLE

在java虚拟机中执行的线程处于此状态

BLOCKED

被阻塞等待监听器锁定的线程处于此状态

WAITING

正在等待一个线程执行特定动作的线程处于此状态

TIMED _WAITING

正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。

TREMINATED

已退出的线程处于此状态

一个线程可以再给定时间点处于一个状态,这些状态是不反应任何操作系统线程状态的虚拟机状态。

线程分为用户线程和守护线程

虚拟机必须确保用户线程执行完毕

虚拟机不用等待守护线程执行完毕;

如后台记录操作日志奇,监控内存使用等。

isAlive() 判断线程是否还活着,即线程是否还终止

public static void main(String[] args) {

System.out.println(Thread.currentThread().isAlive());

}

setName() 给线程起一个名字

public void run(){

System.out.println(Thread.currentThread()+"-->"+name);

}

getName()获取线程名字

currentThread()获取当前正在运行的线程对象,也就是获取自己本身

package cm.cl.sj;

public class StartDead {

private int i;

private void run() {

for (; i < 100; i++) {

System.out.println(getName() + "" + i);

}

}

private boolean getName() {

}

public static void main(String[] args) {

StartDead sd = new StartDead();

for (int i = 0; i < 300; i++) {

System.out.println(Thread.currentThread().getName() + "" + i);

if (i == 20) {

sd.start();

System.out.println(sd.isAlive());

}

if (i > 20 && !sd.isAlive()) {

sd.start();

}

}

}

}

不要对处于死亡状态的线程调用Start()方法,程序只能对新建状态的线程调用start()方法,对新建状态的线程两次调用start()方法是错误的,这都会引发illegalThreadStatesdException异常。

前台线程死亡,JVM会通知后台线程死亡,但从它接收指令到作出相应,需要一定时间,而且要将某个线程设置为后台线程,必须在该线程启动之前设置,也就是说,setDaemon(true)必须在start()方法之前调用,否则会引发illegalThreadException异常。C:\Windows\SysWOW64\Macromed\Flash

同步代码块:文件并发访问,当有两个进程并发修改同一个文件时有可能造成异常,故多线程支持引用了同步监视器来解决,使用同步监视器的通用方法就是同步代码块:

synchronized(obj){//obj及时同步监视器,含义是线程开始执行同步代码块之前,必须获得对同步监视器的锁定。

java的多线程安全支持还听过了同步方法,同步方法就是使用synchronized类关键字来修饰某个方法,该方法称为同步块。同步方法的同步监视器是this,也就是调用该方法的对象。线程安全的类具有如下特征:

1,该类的对象可以被多个线程安全的访问

2,每个线程调用该对象的任一方法之后将得到的正确的结果

3,每个线程调用该对象任意方法之后,该对象状态依旧保持合理状态。

注意,不可变类总是线程安全的,因为他的对象状态不可改变。但可变对象需要额外的方法来保证其线程安全。

synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,成员变量。

public void run(){

account.draw(drawAmount);

}

加锁----修改----释放锁

可变类的线程安全是以降低程序的运行效率作为代价的,为了减少线程安全所带来的负面影响,线程可以采用如下策略:

不要对线程安全类的所有当大都进行同步,只对那些会改变竞争资源 (也就是共享资源)的方法进行同步。

如果可变类有两种运行环境:单线程和多线程环境,则应该为该可变类提供两种版本,即线程不安全版本和线程安全版本。单线程环境中使用线程不安全版本以保持性能,在多线程环境中使用线程安全版本。

同步锁:通过显式定义同步锁对象来实现同步

死锁:两个线程相互等待对方释放同步监视器就会发生死锁,java虚拟机没有监测,也没有采取措施来处理死锁情况,所以多线程编程时应避免死锁情况,一旦出现死锁,整个程序几部发生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态无法继续。

注意:由于Thread类的suspend()方法也很容易导致死锁,所以java不在推荐使用该方法来暂停线程的执行。

yield

public static void yield()

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

sleep

public static void sleep(long millis) throws InterruptedException

在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。

参数:

millis - 以毫秒为单位的休眠时间。

nanos - 要休眠的另外 0-999999 纳秒。

抛出:

IllegalArgumentException - 如果 millis 值为负或 nanos 值不在 0-999999 范围内。

InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

start

public void start()

使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。

多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

抛出:

IllegalThreadStateException - 如果线程已经启动

run

public void run()

如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

Thread 的子类应该重写该方法。

指定者:

接口 Runnable 中的 run

interrupt

public void interrupt()

中断线程。

如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException

如果线程在调用 Object 类的 wait()wait(long)wait(long, int) 方法,或者该类的 join()join(long)join(long, int)sleep(long)sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException

如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException

如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。

如果以前的条件都没有保存,则该线程的中断状态将被设置。

中断一个不处于活动状态的线程不需要任何作用。

抛出:

SecurityException - 如果当前线程无法修改该线程。

currentThread

public static Thread currentThread()

返回对当前正在执行的线程对象的引用。

返回:

当前执行的线程。

isDaemon

public final boolean isDaemon()

测试该线程是否为守护线程。

返回:

如果该线程是守护线程,则返回 true;否则返回 false。

getName

public final String getName()

返回该线程的名称。

返回:

该线程的名称。

wait()

导致当前线程等待,直到其他线程调用该同步监视器notify()方法或notifyAll()方法来唤醒该线程。

notify()

唤醒在此同步监视器上等待的单个县城。如果所有线程都在西同步监视器上等待,则会选择缓刑期中一个线程,选择是任意的,只有当前线程放弃该同步监视器的锁定后,才可以执行被唤醒的线程。

notifyAll()

唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值