多线程相关的概念
1、程序(Program)
为实现一个功能,完成一个任务而选择一种编程语言编写的一组指令的集合。
2、进程(Process)
程序的一次运行。操作系统会给这个进程分配资源。
进程是操作系统分配资源的最小单位。
进程与进程之间的内存是独立,无法直接共享。
3、线程(Thread)
线程是进程中的其中一条执行路径。一个进程中至少有一个线程,也可以有多个线程。有的时候也把线程称为轻量级的进程。
同一个进程的多个线程之间有些内存是可以共享的(方法区、堆),也有些内存是独立的(栈(包括虚拟机栈和本地方法栈)、程序计数器)。
两种实现多线程的方式
1、继承Thread类
class MyThread extends Thread {
public void run(){
//...
}
}
class Test{
public static void main(String[] args){
MyThread my = new MyThread();
my.start();
}
2、实现Runnable接口
class MyRunnable implements Runnable{
public void run(){
//...
}
}
class Test {
public static void main(String[] args){
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
t1.start();
t2.start();
}
}
Thread的相关API
1、构造器
-
Thread()
-
Thread(String name)
-
Thread(Runnable target)
-
Thread(Runnable target, String name)
-
2、其他方法
(1)public void run()
(2)public void start()
(3)获取当前线程对象:Thread.currentThread()
(4)获取当前线程的名称:getName()
(5)设置或获取线程的优先级:set/getPriority()
优先级的范围:[1,10],Thread类中有三个常量:MAX_PRIORITY(10),MIN_PRIORITY(1),NORM_PRIORITY(5)
优先级只是影响概率。
(6)线程休眠:Thread.sleep(毫秒)
(7)打断线程:interrupt()
(8)暂停当前线程:Thread.yield()
(9)线程要加塞:join()
-
xx.join()这句代码写在哪个线程体中,哪个线程被加塞,和其他线程无关。
(10)判断线程是否已启动但未终止:isAlive()
-
关键字:synchronized
-
1、什么情况下会发生线程安全问题?
(1)多个线程
(2)共享数据
(3)多个线程的线程体中,多条语句再操作这个共享数据时
2、如何解决线程安全问题?同步锁
形式一:同步代码块
形式二:同步方法
3、同步代码块
-
synchronized(锁对象){
//一次任务代码,这其中的代码,在执行过程中,不希望其他线程插入
} -
锁对象:
-
(1)任意类型的对象
(2)确保使用共享数据的这几个线程,使用同一个锁对象
4、同步方法
synchronized 【修饰符】 返回值类型 方法名(【形参列表】)throws 异常列表{
//同一时间,只能有一个线程能进来运行
}
锁对象:
(1)非静态方法:this(谨慎)
(2)静态方法:当前类的Class对象
线程通信
1、为了解决“生产者与消费者问题”。
当一些线程负责往“数据缓冲区”放数据,另一个线程负责从“数据缓冲区”取数据。
问题1:生产者线程与消费者线程使用同一个数据缓冲区,就是共享数据,那么要考虑同步
问题2:当数据缓冲区满的时候,生产者线程需要wait(), 当消费者消费了数据后,需要notify或notifyAll
当数据缓冲区空的时候,消费者线程需要wait(), 当生产者生产了数据后,需要notify或notifyAll
2、java.lang.Object类中声明了:
(1)wait():必须由“同步锁”对象调用
(2)notfiy()和notifyAll():必须由“同步锁”对象调用