进程(Process)是程序的一次动态执行过程,它对应了从代码加载丶执行至执行完毕的一个完整过程,这个过程也是进程本身从产生丶发展至消亡的过程。操作系统同时管理一个计算机系统中的多个进程,让计算机系统中的多个进程轮流使用CPU资源,或者共享操作系统的其他资源。
线程是进程中执行运算的最小单位,可完成一个独立的顺序控制流程。每个进程中,必须至少建立一个线程(这个线程称为主线程)来作为这个程序运行的入口点。如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为"多线程"。在操作系统将进程分成多个线程后,实际上每个任务是一个线程,多个线程共享相同的地址空间并且共同分享同一个进程,这些线程可以在操作系统的管理下并发执行。从而大大提高了程序的运行效率。虽然线程的执行看似是多个线程同时执行,但实际上并非如此。由于单CPU的计算机中,CPU同时只能执行一条指令,因此,在仅有一个CPU的计算机上不可能同时执行多个任务。而操作系统为了能提高程序的运行效率,将CPU的执行时间分成多个时间片,分配给不同的线程,当一个时间片执行完毕后,该线程就可能让出CPU使用权限交付给下一个时间片的其他线程执行。当然有可能相邻的时间片分配给同一线程。之所以表面上看是多个线程同时执行,是因为不同线程之间切换的时间非常短,也许仅仅是几毫秒,对普通人来说是难以感知的,这样就看似多个线程在同时执行了。
构造方法 | 说明 |
Thread() | 分配新的Thread对象 |
Thread(Runnable target) | 分配新的Thread对象,target为run()方法被调用的对象 |
Thread(Runnable target,String name) | 分配新的Thread对象,target为run()方法被调用的对象,name为新线程的名称 |
void run() | 执行任务操作的方法 |
void start() | 使该线程开始执行,Java虚拟机调用该线程的run()方法 |
void sleep(long millis) | 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行) |
String getName() | 返回线程的名称 |
int getPriority() | 返回线程的优先级 |
int setPriority(int newPriority) | 更改线程的优先级 |
static Therad currentThread() | 返回当前正在执行的线程对象的引用 |
boolean isAlive() | 测试线程是否处于活动状态 |
void join() | 使当前线程暂停执行,等待调用该方法的线程结束后再继续执行本线程 |
void interrupt() | 中断线程 |
void yield() | 暂停当前正在执行的线程对象,并执行其他线程 |
4.1.继承Thread类创建线程
①.定义MyTherad类继承Therad类
②.重写run()方法,在run()方法中实现数据输出
③.创建线程对象,调用start()方法启动线程
4.2.实现Runnable接口创建线程
①.定义MyRunnable类实现Runnable接口,并实现Runnable接口的run()方法,在run()方法中实现输出数据。
②.创建MyRunnable类的对象myRunnable
③.创建一个Thread类的对象myThread,将myRunnable对象作为Thread类构造方法的参数传入。
④.调用myThread对象的start()方法启动线程。
总结:
两种创建线程的方式有各自的特点和应用领域:直接继承Thread类的方式,编写简单,可以直接操作线程,适用于单继承的情况;当一个线程继承了另一个类时,就只能用实现Runnable接口的方式来创建线程,而且这种方式还可以实现多个线程之间资源的共享。
①.Thread t1=new Thread(rd); 创建状态
②.t1.start(); 线程就绪状态
③.CPU资源分配给你了 你开始执行了 运行状态
④.调用了Thread.sleep(100); 休眠(阻塞)状态
可能使线程暂停执行的条件如下。
⑤.System.exit(0)程序结束 死亡状态
1.同步方法
使用synchronized修饰的方法控制对类成员变量的访问。每个类实例对应一把锁,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对应一个实例,从而有效避免了类成员变量的访问冲突。
语法:
访问修饰符 synchronized 返回值类型 方法名 (参数列表){///省略方法体......}
或者
synchronized 访问修饰符 返回值类型 方法名 (参数列表){///省略方法体......}
2.同步代码块
代码块即使用{}括起来的一段代码,使用synchronized关键字修饰的代码块,称为同步代码块。
语法:
synchronized(this){///省略方法体......}
1.多线程允许程序员编写可最大程度利用CPU的高效程序
2.在Java程序启动时,一个线程立刻运行,该线程通常称为程序的主线程。主线程的重要性体现在以下两个方面。
3.可通过两种方式创建线程
4.每一个线程创建和死亡之前,均会处于创建丶就绪丶运行丶阻塞丶死亡状态之一
5.在Java实现的多线程应用程序中,可以通过调用Thread类中的方法来实现对线程对象的操作
6.当多个线程对象操纵同一共享资源时,要使用 synchronized关键字来进行资源的同步处理,可以使用同步方法和同步代码块来实现线程同步
练习小作业:
1.创建两个线程。每个线程均输出20次消息数字丶"你好",线程名。并观察多个线程交替执行的过程。
要求:
使用继承Therad类的方式创建线程。
实现Therad类的run()方法,编写线程执行体。
使用start()方法启动线程。
2.修改题目1,要求线程类使用实现Runnable接口的方式创建,并修改测试类。运行效果与题目一一样。
3.使用多线程模拟多人徒步爬山的过程,每个线程代表一个人,爬山的速度不同,每爬完100米显示信息,爬到终点时给出相应提示。需要设置爬山人名丶爬山的总千米数丶每爬100米的耗时。运行结果。
要求:
使用任意一种方式创建线程
使用Thread.sleep()方法设置线程休眠
4.任意创建一个线程类,在测试类中创建子线程对象,显示主线程丶子线程默认优先级,将主线程设置为最高优先级,子线程设置为最低优先级并显示。运行结果。
5.某医院设置有普通号和特需号,假定某科室一天需看普通号50个,特需号10个,每个特需号的看病时间约是普通号的两倍。开始时普通号和特需号并行叫号,叫到特需号的概率比普通号高,当普通号叫完第10号时,要求先看完全部特需号,再看普通号,请使用多线程模拟这一过程。运行结果。
6.学校召开春季运动会,现使用多线程模拟1000米接力赛跑,比赛地点在学校操场,有多人参加,每人跑100米,每跑10米显示信息,跑够100米之后将接力棒传给下一个选手。要求在跑的选手只有一人,跑到终点时结束。要求使用同步方法和同步代码块两种方式实现线程同步。运行结果。
要求:
实现多线程间数据的共享
使用同步方法或同步代码块实现线程安全
7."桃跑跑" "张票票" "黄牛党"共同抢十张票,限制黄牛党只能抢一次票,请使用多线程模拟此过程。运行结果。