Java多线程

线程总结(一)

一.线程的概述

1.定义:
 线程是程序执行的一条路径,一个进程可以包含多条线程。
多线程并发可以提高程序效率,同时完成多项工作
2.并发与并行:
并发:两个任务同时进行,需要多核cpu
并行:两个任务都请求运行,但处理器只接收一个任务,所以将两个任务安排轮流进行

二.线程的创建和启动:

1.新建:
1>.继承Thread:

public static void main(String[] args)
{
	MyThread mt=new MyThread();
	mt.start();
	for(int i=0;i<10;i++)
	{
		System.out.println("bb");
	}
}
class MyThread extends Thread//继承Thread
{
	public void run()//重写run方法
	{
		for(i=0;i<10;i++)
		{
			System.out.println("aaaaa");
		}
	}
}

2>.声明实现Runnable接口

public static void main(String[] args)
{
	MyRunnable mr=new MyRunnable();
	Thread t=new MyRunnable();//创建Runnable子类对象
	Thread t=new Thread(mr);//将其作为参数传递给Thread构造函数
	t.start();
	for(int i=0;i<10;i++)
	{
		System.out.println("bb");
	}
}
class MyThread implements Runnable
{
	public void run()
	{
		for(i=0;i<10;i++)
		{
			System.out.println("aaaaa");
		}
	}
}

两种方式的区别:

1.继承Thread:子类重写了Thread类的run()方法,当调用start()时,直接找子类的run()方法
2.实现Runnable:构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空,编译看Runnable的run方法,运行时看子类的run()方法。

比较两种方法的好与坏:
继承Thread:

好处:可以直接使用Thread类中的方法,代码简单
弊端:如果已经有了父类,则不能使用该方法

实现Runnable接口:

好处:即使定义的线程有了父类,也可以通过接口实现
弊端:不能直接使用Thread中的方法,需要通过先获取到线程的对象后,才能得到Thread方法,代码复杂

三.线程的生命周期:

1.新建和就绪状态:
新建:
 使用关键字new关键字创建一个线程之后,该线程处于新建状态,与其他对象一样,只是分配了内存,初始化了成员变量的值,并没有其他的任何线程的特征

就绪:
 当线程调用了start方法之后,该线程处于就绪状态,但该状态的程序并没有开始运行,只是表示可以运行,至于何时运行取决于JVM里线程的调度器的调度
启动线程用start方法,而不是run方法

  1. 运行和阻塞状态:
    运行:
     计算机只有一个cpu,任何时候只有一条线程处于运行状态,但当一条线程开始运行后,不会一直处于运行状态,其会被中断,为了使其他线程获得执行的机会,但选择下一个线称时会考虑线程的优先级

调整线程的优先级:
MAX_PRIORITY:取值为10,表示最高优先级
MIN _PRIORITY:取值为1,表示最低优先级
NORM_PRIORITY:取值为5,表示默认优先级

阻塞:
当发生如下状态时,线程进入阻塞状态:

1.调用sleep方法
2.调用一个阻塞式IO方法,在方法返回之前,线程被阻塞
3.线程视图获得一个同步监视器,但该同步监视器正在被其他线程所持
4.线程正在等待某个通知(notify)
5.程序调用线程的suspend方法将该线程挂起,但该方法易导致死锁

解决策略:

1.调用的sleep方法的线程经过了指定的时间
2.线程调用的阻塞式IO方法已经返回
3.线程成功的获得了试图取得的同步监视器
4.线程正在等待某个通知,其他线程发出了一个通知
5.处于挂起的线程被调用了resume恢复方法

在这里插入图片描述
如图可以看出,线程从阻塞状态只能进入就绪状态,无法进行运行状态,就绪状态和运行状态之间的转化不受程序控制,是由系统线程调度所导致,但调用yield()可以让当前处于运行状态的线程转入就绪状态

3.线程死亡:

run()方法执行完成,线程正常结束
线程抛出一个未捕获的Exception或Error
直接调用线程的stop()方法来结束该线程,但其易导致死锁

当主线程结束时,其他线程不受任何影响,一旦子线程启动,其拥有和主线程相同的地位,不受主线程的影响

判断某条线程是否已经死亡,可以调用该线程对象的isAlive()方法,当线程处于就绪,运行,阻塞三种状态时,该方法返回true,当线程处于新建和死亡两种状态时,返回false

不能对死亡状态的线程调用run方法,只能是新建的线程

四.控制线程:

1.加入线程:

join()//当前线程暂停,等待指定线程结束后,当前线程再继续
join(int)//可以等待指定的毫秒之后再继续

2.后台线程:
该线程在后台执行,其任务是为其他线程提供服务,这种被称为“后台线程”,或者“守护线程”,“精灵线程”
SetDaemon,设置一个线程为守护线程,该线程不会单独执行,当其他非守护线程结束后,自动退出。即当非守护线程结束,其他线程也结束

t2.setDameon(true);//当传入true,意味着设置为守护线程

3.休眠线程:

Thread .sleep(毫秒,纳秒);
//核心代码:
try
{
	sleep(100);
}catch(InterruptedException e)
{
	throw new RuntimeException(e);
}

当前线程休眠几秒,后继续运行

4.礼让线程:
yield 让出cpu,只是让当前正在执行的线程暂停,但不会阻止该线程,只是让该线程进入就绪状态

Thread.yield();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值