【1】、首先我们要先了解进程,线程,多线程这几个概念:
进程:
应用程序的执行实例;
有独立的内存空间和系统资源。
线程:
CPU调度和分派的基本单位;
执行运算的最小单位,可完成一个独立的顺序控制流程。
什么是多线程:
如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程”。
多个线程交替占用CPU资源,而非真正的并行执行。
主线程:
main()方法即为主线程入口;
产生其他子线程的线程;
必须最后完成执行,因为它执行各种关闭动作。
【2】、多线程的好处:
充分利用CPU的资源,提升代码性能;
简化编程模型,更好的软件设计和架构;
带来良好的用户体验。
【3】、创建线程的三种方式:
一. 继承Thread类创建线程:(便于代码复用,编写简单,可直接操控线程;适用于单继承)
定义MyThread类继承Thread类;
重写run()方法,编写线程执行体;
创建线程对象,调用start()方法启动线程。
//获取当前主线程
Thread t=Thread.currentThread();
String name=thread.getName();
System.out.println("当前线程是:"+t.getName());
t.setName("MyJavaThread");
name=thread .getName();
System.out.println("当前线程是:"+t.getName());
二.实现Runnable接口创建线程:(用处广泛,便于扩展)
这里也是推荐使用实现Runnable接口方式创建线程
定义MyRunnable类实现Runnable接口;
实现run()方法,编写线程执行体;
创建线程对象,调用start()方法启动线程。
构造方法1.-----Thread(Runnable target)
构造方法2.-----Thread(Runnable target,String name)
三、实现接口Callable接口创建线程:(可以获取返回值)(不常用)
定义类实现Callable接口;
实现call()方法,可以改写return返回值,编写线程执行体;
创建线程对象,调用start()方法启动线程,get()方法调用返回值。
****** 三种才能创建线程的不同点:
当需要多个线程各自完成各自任务时,可以用继承Thread类创建线程
当需要多个线程共同完成一个任务时,可以用实现Runnable接口创建
当需要返回值时,可以实现Callable接口创建
【4】、线程的状态:创建、就绪、运行、阻塞、死亡
线程休眠:
线程调度:
线程优先级:
方法是Thread.setPriority(级别为1-10)//设置优先级
线程的强制运行:
join()
等待该线程终止;
等待加入的其他线程结束后再继续执行本线程
线程的礼让:
yield()
暂停当前正在执行的线程对象,并执行其他线程,线程礼让。
只是提供一种可能,但是不能保证一定会实现礼让。
请注意区分join()
yield():礼让,放手。当前线程处于就绪状态;
join():阻塞当前线程,直到其他线程执行完毕,当前线程才进入就绪状态
【5】、多线程可能引发的安全问题:
常见的线程安全的类型:
ArrayList-->Vector
HashMap-->HashTable(旧)
-->ConcurrentHashMap
StringBuilder-->StringBuffer
多线程共享数据:
可能带来的问题:数据不安全
原因:多线程共同操作数据时,引发的冲突(如延迟时,操作未全部完成等等)
如何解决:(线程同步,即各线程之间要有个先来后到,不能一窝蜂)
(线程同步其实是“排队”:上锁,排队,一个一个来,不能同时操作)
1.同步方法:
使用synchronized修饰的方法控制对类成员变量的访问
访问修饰符synchronized返回类型 方法名(参数列表){......}
synchronized访问修饰符 返回类型 方法名(参数列表){.....}
(synchronized相当为当前的线程声明一把锁)
2.同步代码块
使用synchronized关键字修饰的代码块
synchronized(syncObject){
//需要同步的代码
}
syncObject为需同步的对象,通常为this
效果与同步方法相同
多个并发线程访问同一个资源的同步代码块时
同一时刻只能有一个线程进入synchronized(this)同步代码块;
当一个线程访问另一个synchronized(this)同步代码块时,其他
synchronized(this)同步代码块同样被锁定;
当一个线程访问一个synchronized(this)同步代码块时,其他线程
可以访问该资源的非synchronized(thi)同步代码。



