1、概述
进程:是一个正在运行的程序。
线程:进程中的一个独立控制单元,控制着进程的执行。
2、Thread类
在自定义代码中,自定义一个线程(Thread类)
第一种方式
- 继承Thread类。
- 重写run方法。
- 调用start方法。
▲为何覆盖run方法
Thread类用于描述线程
该类就定义了一个功能,用于存储线程要运行的代码–>run方法。
Thread类中的run方法,用于存储线程要运行代码。
▲调用当前对象
Thread.currentThread();获取当前对象
getName;获取线程名称
setName;设置线程名称
class Demo extends Thread //1、定义类继承Thread
{
public void run() //2、重写run方法
{
System.out.println("demo run");
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo(); //创建一个线程
d.start(); //3、调用线程start方法,启动线程,调用run方法
}
}
第二种方式
实现Runable接口的类
- 定义类,实现Runable接口。
- 实现Runable中的Run方法。
- 通过Thread类建立线程对象。
- 将Runable接口的子类对象作为实际参数,传递给Thread类的构造函数。
- 调用Thread类的start方法,开启线程并调用Runable接口子类中的Run方法。
class Demo implements Runable //1、定义类实现Runable接口
{
public void run() //2、重写run方法
{
System.out.println("demo run");
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo(); //创建一个线程
Thread d1 = new Thread(d);//建立线程对象并传递给Thread类的构造函数
d.start(); //3、调用线程start方法,启动线程,调用run方法
}
}
注:实现方式与继承方式的区别:
实现方式:好处是能够避免单继承的局限性。
继承Thread类,线程代码存放Thread类中Run方法中。
实现Runable 线程代码存放在接口的子类Run方法中。
3、同步代码快
synchronized(对象)
{
需要被同步的代码
}
前提:必须有两个或两个以上的线程才用同步,必须是多个线程用一个锁。
▲同步函数:public synchronized void add( )this
class Ticket extends thread
{
private int tick = 100;
Object obj = new obj();
public void run()
{
while(ture)
{
synchronized(obj)
{
if(tick>0)
{
System.out.println(Thread.currentThread().getName()+tick--)
}
}
}
}
}
class TickDemo
{
public static void main (String[] args)
{
Tick t = new Tick();
Thread t1 = new Thread();
t1.start(t);
}
}
4、进程间通信
多个线程操作同一个资源,但操作的动作不同
wait()、notify()、notefyAll()()——等待唤醒;
都使用在同步中,因为要对监视器(锁)进行操作,所以要在同步中,因为只有在同步中才有锁。
▲为何操作线程的方法都定义在object类中?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程共有的锁,同一个锁上的被wait()的线程,被同一个锁上的notefy()唤醒。
5、停止线程
停止线程的方法:Run方法结束。
当没有指定的方法让冻结的线程恢复到运行状态时,需要对冻结进行清除,强制让线程恢复到运行状态中来,可操作标记让线程结束,Thread类中提供方法:interrupt();
6、守护线程
必须在线程启动前启用。
当前台线程结束,只剩下守护线程时,Java虚拟机退出。
7、Join
抢夺CPU执行权。
当A线程执行到了B线程的Join方法时,A线程就会等待,等B线程全部执行完,A线程才会执行,Join可以用来临时加入线程执行。