Java之线程

it2022-06-29  70

线程 首先需要了解,什么是线程? 线程不是进程,但其行为很像进程,线程是比进程更小的执行单位,一个进程在其执行的过程中,可以产生多个线程。线程是程序执行的一条路径,一个进程可以包含多条线程。多线程并发执行可以提高程序的效率,可以同时完成多项工作。

线程的生命周期 1、新建:新创建一个线程对象。 2、可运行:线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获得cpu的使用权。 3、运行:可运行状态的线程获得了cpu时间片(timeslice),执行程序代码。 4、阻塞:阻塞状态是指线程因为某种原因放弃了cpu的使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行状态,才有机会再次获得cpu timeslice转到运行状态。阻塞的情况分为三种:等待阻塞、同步阻塞、其他阻塞。 5、死亡:线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次重生。

多线程并行和并发的区别 多线程并发可以提高程序的效率,那么并行和并发的区别是什么? 并行是两个任务同时运行,在A任务执行的同时,B任务也在执行(需要多核CPU)。 并发是指多个任务都请求运行,而处理器只能接受一个任务,把多个任务安排轮流执行,由于时间间隔较短,让人感觉多个任务在同时运行。

实现多线程的两种方法 一、继承Thread:定义类继承Thread;重写run方法;把新线程做的事写在run()方法中;创建线程对象;开启新线程,自动执行run()方法。

package com.hpu.edu.dong; public class dong { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub MyThread mt=new MyThread(); mt.start(); for (int i = 0; i < 10; i++) { System.out.println("2"); } } } class MyThread extends Thread{//继承Thread @Override public void run() { //重写run方法 // TODO Auto-generated method stub for (int i = 0; i < 5; i++) { System.out.println("1"); } } }

二、实现Runnable接口 定义类实现Runnable接口;实现run方法;把新线程做的事写在run方法中;创建自定义的Runnable的子类对象;创建Thread对象,传入Runnable;调用start()开启新线程,内部会自动调用Runnable的run()方法。

package com.hpu.edu.dong; public class dong { public static void main(String[] args){ // TODO Auto-generated method stub MyRunnable mr=new MyRunnable();//创建Runnable的子类对象 Thread t=new Thread(mr); //将其当作参数传递给Thread的构造函数 t.start(); //开启线程 for (int i = 0; i < 8; i++) { System.out.println("2"); } } } class MyRunnable implements Runnable{//定义一个类实现Runnable @Override public void run() {//重写run方法 // TODO Auto-generated method stub for (int i = 0; i < 5; i++) {//写入要执行的代码 System.out.println("1"); } } }

两种方法的区别 区别: 继承Thread:由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法。 实现Runnable:构造函数中传入了Runnable的引用,start()调用run()方法时内部判断成员变量Runnable()的引用是否为空,不为空编译时看的是Runnable()的run(),运行时执行的是子类的run()方法。 继承Thread: 好处:可以直接使用Thread类中的方法,代码简单; 弊端:如果已经有了父类,就不能使用这种方法。 实现Runnable接口 好处:定义的线程有父类也没影响,因为有了父类也可以实现接口,而且接口是多实现的。 弊端:不能直接使用Thread中的方法,需要先获取到线程对象后,才能得到Thread的方法,代码复杂。

同步代码块 首先先了解什么是同步?假设有两段代码块,在同一时间只能执行一段,在这段代码块没执行结束之前,不会执行另外一段代码块。 什么情况下需要同步?当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中cpu不要切换到其他线程工作,这时就需要同步。 同步代码块的使用需要用到关键字:synchronized。

package com.hpu.edu.dong; public class dong { public static void main(String[] args){ // TODO Auto-generated method stub final weapon wp=new weapon(); new Thread(){ public void run() { while(true){ wp.print1(); } } }.start(); new Thread(){ public void run() { while(true){ wp.print2(); } } }.start(); } } class weapon{ syn s=new syn(); public void print1(){ synchronized (s) { System.out.print("圣"); System.out.print("耀"); System.out.print("救"); System.out.print("赎"); System.out.print("\r\n"); } } public void print2(){ synchronized(s){ System.out.print("苍"); System.out.print("穹"); System.out.print("幕"); System.out.print("落"); System.out.print("\r\n"); } } } class syn{ }

死锁 死锁定义:多个进程在执行的过程中,因争夺同类资源且资源分配不当而造成的一中互相等待的现象。若无外力作用,它们都将永远无法继续执行,这种状态称为死锁,这些处于等待状态的进程称为死锁进程。 死锁出现的条件:一、必须是两个或者两个以上进程(线程);二、必须有竞争资源。 例子:假设线程1在执行的时候占用了资源1,此时,需要占用资源2才能继续执行,同时线程2使用了资源2,需要占用资源1才能继续执行:

package com.hpu.edu.dong; public class dong1 { private static String s1="线程1"; private static String s2="线程2"; private static String R1="资源1"; private static String R2="资源2"; public static void main(String[] args) { // TODO Auto-generated method stub new Thread(){ @Override public void run() { // TODO Auto-generated method stub while(true){ synchronized (s1) { System.out.println(getName()+s1+"使用"+R1+"请求"+R2); synchronized(s2){ System.out.println(getName()+"获取"+R2+"执行"); } } } } }.start(); new Thread(){ @Override public void run() { // TODO Auto-generated method stub while(true){ synchronized (s2) { System.out.println(getName()+s2+"使用"+R2+"请求"+R1); synchronized(s1){ System.out.println(getName()+"获取"+R1+"执行"); } } } } }.start(); } }

运行结果:

Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-0获取资源2执行 Thread-0线程1使用资源1请求资源2 Thread-1线程2使用资源2请求资源1

造成了死锁的现象。


最新回复(0)