通俗易懂-进程和线程的讲解
进程和线程:
1)进程是静态的,其实就是指开启的⼀个程序;⽽线程是动态的,是真正执⾏的单元,执⾏的过程。其实我们平时看到的进程,是线程在执⾏着,因为线程是作为进程的⼀个单元存在的。
2)同样作为基本的执⾏单元,线程是划分得⽐进程更⼩的执⾏单位。
3)每个进程都有⼀段专⽤的内存区域。与此相反,线程却共享内存单元(包括代码和数据),通过共享的内存单元来实现数据交换、实时通信与必要的同步操作。
创建线程的⽅式:
⽅式⼀:继承Thread
1:定义⼀个类继承Thread
2:覆盖Thread中的run⽅法(将线程运⾏的代码放⼊run⽅法中)。
3:直接创建Thread的⼦类对象
4:调⽤start⽅法(内部调⽤了线程的任务(run⽅法));作⽤:启动线程,调⽤run⽅法
//继承Thread的例⼦:
class Test extends Thread
{
public void run()
{
System.out.println(Thread.currentThread().getName() + "执⾏线程");
//Thread.currentThread():获取当前线程对象
}
}
class ThreadTest
{
public static void main(String[] args)
{
Test t1 = new Test();
t1.start();
}
}
⽅式⼆:实现Runnable
1:定义类实现Runnable接⼝
2:覆盖Runnable接⼝中的run⽅法,将线程的任务代码封装到run中
3:通过Thread类创建线程对象
4、并将Runnable接⼝的⼦类对象作为Thread类的构造函数参数进⾏传递
//实现Runnable接⼝例⼦:
class Ticket implements Runnable
{
public void run()
{
System.out.println(Thread.currentThread().getName() + "执⾏线程");
}
}
class TicketDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread t1 = new Thread(t);//创建了⼀个线程;
t1.start();
}
}
区别:
继承⽅式:线程代码放在Thread⼦类的run⽅法中
实现⽅式:线程代码放在接⼝的⼦类run⽅法中;避免了单继承的局限性,建议使⽤。
extends关键字
在 Java 中,类的继承是单⼀继承,也就是说,⼀个⼦类只能拥有⼀个⽗类,所以 extends 只能继承⼀个类。
implements关键字
使⽤ implements 关键字可以变相的使java具有多继承的特性,使⽤范围为类继承接⼝的情况,可以同时继承多个接⼝(接⼝跟接⼝之间采⽤逗号分隔)。
⼆者区别,⼀个是继承(可以有构造函数),⼀个是接⼝的实现(并没有什么构造函数),只是接⼝,可以被其他类继承⽽已
线程状态:
新建:start()
临时状态:具备cpu的执⾏资格,但是⽆执⾏权
运⾏状态:具备CPU的执⾏权,可执⾏
冻结状态:通过sleep或者wait使线程不具备执⾏资格,需要notify唤醒,并处于临时状态。
消亡状态:run⽅法结束或者中断了线程,使得线程死亡。
3、多线程安全问题:
多个线程共享同⼀数据,当某⼀线程执⾏多条语句时,其他线程也执⾏进来,导致数据在某⼀语句上被多次修改,执⾏到下⼀语句时,导致错误数据的产⽣。
一个线程可以包含多个进程因素:多个线程操作共享数据;多条语句操作同⼀数据
解决:
原理:某⼀时间只让某⼀线程执⾏完操作共享数据的所有语句。
办法:使⽤锁机制:synchronized或lock对象
线程的同步:
当两个或两个以上的线程需要共享资源,他们需要某种⽅法来确定资源在某⼀刻仅被⼀个线程占⽤,达到此⽬的的过程叫做同步(synchronization)。
同步代码块:synchronized(对象){},将需要同步的代码放在⼤括号中,括号中的对象即为锁。同步函
数:放于函数上,修饰符之后,返回类型之前。
wait和sleep的区别:(执⾏权和锁区分)
wait:可指定等待的时间,不指定须由notify或notifyAll唤醒。
线程会释放执⾏权,且释放锁。
sleep:必须制定睡眠的时间,时间到了⾃动处于临时(阻塞)状态。
即使睡眠了,仍持有锁,不会释放执⾏权。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论