多线程学习

1.线程与进程的区别

进程其实就是一个应用程序,进程是所有线程的集合,每个线程是进程中的一条执行路径。

进程之间不能共享数据,但线程可以。

系统创建进程需要重新分配系统资源,创建线程代价比较小。

java语言内置了多线程功能支持,简化了java多线程编程。

2.为什么要使用多线程

多线程能提高程序的效率

3.多线程应用场景

主要能体现多线程提高程序效率  比如迅雷多线程下载、分批发送短信。

4.多线程的创建方式

继承Thread类

public class ThreadDemo01 {

	public static void main(String[] args) {
		//实例化Thread子类,创建线程对象
		ExtendsThread extendsThread = new ExtendsThread();
		//调用线程对象的start方法  不能直接调用run方法
		extendsThread.start();
	}
	
}

//定义一个继承Thread的子类  并重写run方法
class ExtendsThread extends Thread{
	//run方法里是线程需要执行的任务 执行的代码
	public void run(){
		
	}
}

实现Runnable接口

public class ThreadDemo02 {

	public static void main(String[] args) {
		
		//先创建Runnable实现类的实例
		ImplementsRunnable implementsRunnable = new ImplementsRunnable();
		//不能直接调用implementsRunnable的run方法
		//如果直接调用run方法的话  并没有创建线程  仍然是在主线程中
		//需要实例化一个Thread  并把implementsRunnable作为Thread的target对象
		Thread thread = new Thread(implementsRunnable);
		//然后调用Thread的start方法启动线程
		thread.start();
		
	}
}

//定义一个实现Runnable接口的实现类  重写run方法
class ImplementsRunnable implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
	
}

匿名内部类方式

public class ThreadDemo03 {

	public static void main(String[] args) {
		/**
		 * 匿名内部类指的是没有名字的内部类 正因为没有名字,匿名内部类只能使用一次
		 * 使用匿名内部类有一个条件:必须继承一个父类或者实现一个接口
		 * 匿名内部类不能定义任何静态成员、方法
		 * 匿名内部类的方法不能是抽象的
		 * 匿名内部类访问外部类成员变量或成员方法必须用static修饰
		 * 此处我们使用匿名内部类创建多线程
		 */
		//1.继承Thread父类  重写run方法
		new Thread(){
			
			public void run(){
				
			}
		}.start();
		//2.实现Runnable接口 重写run方法
		new Thread(new Runnable() {
			
			public void run() {
				
			}
		}).start();
		
	}
}

5.为什么不能直接调用run方法  要调用start方法

如果在主线程main方法里直接调用run方法的话,那就没有创建线程,是一个单线程。代码依然是顺序执行。

6.创建线程是继承Thread类好还是实现Runnable方法好

实现Runnable方法更好,因为继承只能继承一个,而实现可以实现多个方法。实现了接口还能继续继承。继承了类就不能再继承。

jdk1.8中文api文档

7.常用线程api方法

start()启动线程
currentThread()获取当前线程名称
getId()

获取当前线程编号

//获取线程的ID ID是多线程随机不重复的主键
System.out.println("getId():"+ getId());
getName()

获取线程名称  Thread-编号  从0开始

System.out.println("getName():"+ getName());
sleep(long mill)休眠线程
stop()停止线程

8.常用线程构造函数

Thread()分配一个新的Thread对象
Thread(String name)分配一个新的Thread对象  具有指定的name
Thread(Runable r)分配一个新的Thread对象
Thread(Runable r,String name)分配一个新的Thread对象

9.多线程运行状态

线程从创建、运行到结束,一共有五个状态。新建、就绪、运行、阻塞、死亡。

新建状态:当用new操作符创建一个线程时,如new Thread(r),线程处于新建状态。在该状态时,程序还没有开始运行线程中的代码。

就绪状态:当创建完线程,调用start()方法后启动线程,当start方法返回后,线程处于就绪状态。处于该状态时,线程不一定会马上去执行run方法,需要同其他线程竞争cpu时间,当获得cpu时间后,才可以运行线程。注:不能重复调用start方法

运行状态:当线程获得cpu时间,进入运行状态,此时开始真正执行run()方法。

阻塞状态:线程运行时,会有各种原因进入阻塞状态。

        等待阻塞

  1. 线程通过调用sleep()方法进入休眠状态。
  2. 线程调用一个在I/O流上被阻塞的操作,就是说该操作不执行完就不会返回给调用者。此时线程也会进入阻塞状态。

        同步阻塞

  1. 线程试图得到一个锁,而该锁被其他线程持有。
  2. 线程正在等待某一个触发条件。

死亡状态:有两个原因:

  1. run()方法正常结束终止线程进入死亡状态。
  2. 一个未捕获的异常终止run()方法使线程猝死。

查看线程是否存活(要么就是可运行的、要么就是阻塞状态),调用isAlive方法。如果可运行或被阻塞,返回true,如果仍是新建状态或不可运行,返回false。

10.线程管理

线程睡眠sleep()使线程进入阻塞状态。sleep(long mill)是静态方法。他睡眠的始终是当前正在运行的线程。所以如果使用Thread的实例对象去调用它,可能达不到想要的效果。

package com.bin;

class DemoThread extends  Thread{

    //在run方法中  不能抛出异常 只能try catch处理
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            //sleep 毫秒数
            try {
                //sleep 让当前线程从运行状态变为休眠状态再到运行状态
                //sleep 不能是释放锁 多线程之间释放同步 wait可以释放锁
                Thread.sleep(1000);
                //获取线程的ID ID是多线程随机不重复的主键
                System.out.println("getId():"+ getId());
                System.out.println("getName():"+ getName());
                //如果是实现Runnable接口创建多线程  那么不能直接调用getId getName方法  要先获                    //取当前线程对象                     System.out.println("Thread.currentThread().getId()+"+Thread.currentThread().getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("i:"+i);

        }
    }
}
public class ThreadDemo05 {

    public static void main(String[] args) {
        DemoThread demoThread = new DemoThread();
        //自定义线程名称
        demoThread.setName("线程1");
        DemoThread demoThread1 = new DemoThread();
        demoThread1.setName("线程1");
        demoThread.start();
        demoThread1.start();
    }

}

线程让步yield(),与sleep()相似,会暂停当前线程,让出cpu资源。

线程合并join(),将几个并行线程合并成一个单线程。

设置线程优先级   setPriority(int newPriority)  1~10 1最低 10最高 默认5  只能反应线程的紧急程度,不能决定线程的执行顺序。

正确结束线程,正常执行完run方法,然后结束掉。通过循环条件判断和标识符去判断。

int i=0;  
boolean next=true;  
@Override  
public void run() {  
    while (next) {  
        if(i==10)  
            next=false;  
        i++;  
        System.out.println(i);  
        }  
    }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值