1、多线程详细笔记含代码java知识点总结多进程1.基本概念:程序、进程、线程程序(program):一组指令的集合,一段静态代码。(完成特定任务的代码,由某种语言编写)进程(process):是一个程序的执行过程(即正在运行的程序)。是个动态过程:有他自身的产生、存在和消亡的过程。 PS:例子:如运行中的QQ,运行中的MP3播放器。 程序和进程区别:程序时静态的,进程是动态的。线程(thread):进程可细分为线程,是一个程序内部的一条执行路径 PS:若一个程序可同一时间执行多个线程,就是支持多线程的何时需要多线程: 1程序需要同时执行多个任务; 2程序需要实现一些需要等待的任务的时候(如用户输
2、入、文件读写操作、网络操作、搜索等。); 3需要一些后台运行的程序时守护线程。(如垃圾回收线程)2.多线程的创建和使用(1)线程的创建(2种方法)1第一种创建:继承于java.lang.Thread类(无需插包)例子: / 1.创建一个继承于Thread的类 class SubThread extends Thread public void run() / 2.重写Thread类的run()方法,方法内实现子线程内要完成的功能 for(int i=0;i100;i+) System.out.println(i); public class TestThread public static v
3、oid main(String args) SubThread st = new SubThread(); / 3.创建一个子类对象 st.start(); / 4.调用线程的start()方法(两个作用:启用此线程,调用相应的run方法) 注意: Thread类常用的方法及作用 1 start()方法。启动线程并执行相应的run方法 2 run()方法。子线程要执行的代码放到run()方法中 3 currentThread()。静态的,调用当前线程(相当于一个当前线程的对象,都是在自己的线程里才用的)。(读音:克(饿) 润特) 4 getName()方法。获得此线程的名字 5 setName
4、()方法。设置此线程的名字 6yield()方法。CPU暂时释放该线程的执行权(也可能在下一次抢到执行权)(读音:亿奥的) 7join()方法(该方法有异常,需要try catch,使用的时候都是调用其他线程,st1.join())。在A线程调用B线程的join方法时,A线停止运行,直至B线程执行结束,A线程再接着join之后的方法继续执行。 8isAlive()方法。判断当前线程是否还存活(返回时布尔值)。 9sleep(long a)方法(需要抛try catch异常)。显示让当前线程睡眠a毫秒。 10线程通信:wait() 、notify()、 notifyAll() 线程优先级的方法(
5、优先级大的线程抢到CPU的概率大点) 11setPriority():设置线程优先级(最小1,最大10(也可表示Thread.MAX_PRIORITY),正常5)(读音:破ruai欧瑞踢 ) 12getPriority():返回线程优先值例子例子1:currentThread()、getName()、setName()class SubThread1 extends Thread public voia run() for(int i=0;i10;i+) System.out.println(Thread.currentThread().getName()+”:”+i); / 调用当前线程的名
6、字,当前线程是st1 public class TestThread1 public static void main(String args) SubThread1 st1= new SubTread1(); st1.setName(“子线程1”); /设置线程st1的名字 st1.start(); /开始st1线程 Thread.currentThread().setName(“主线程”); /设置当前线程的名字(当前线程时主线程) for(int i=0;i10;i+) System.out.println(Thread.crrentThread().getName()+”:”+i);
7、例子2:yield()class SubThread1 extends Thread public voia run() for(int i=0;i10;i+) System.out.println(Thread.currentThread().getName()+”:”+i); public class TestThread1 public static void main(String args) SubThread1 st1= new SubTread1(); st1.setName(“子线程1”); st1.start(); Thread.currentThread().setName
8、(“主线程”); for(int i=0;i10;i+) System.out.println(Thread.crrentThread().getName()+”:”+i); if(i%10=0) Thread.crrentThread().yield(); /当i是10的倍数的时候,主线程暂时释放CPU的执行权 例子3:join() ,该方法有异常,需要try catchclass SubThread1 extends Thread public voia run() for(int i=0;i10;i+) System.out.println(Thread.currentThread().
9、getName()+”:”+i); public class TestThread1 public static void main(String args) SubThread1 st1= new SubTread1(); st1.setName(“子线程1”); st1.start(); Thread.currentThread().setName(“主线程”); for(int i=0;i10;i+) System.out.println(Thread.crrentThread().getName()+”:”+i); if(i=20) /当i等于20的时候,当前线程(主线程)停止运行,并
10、运行线 程st1,当st1运行结束,继续运行主线程 */ try st1.join(); catch(InterrupterException e) e.printStackTrace(); 例子4:isAlive() class SubThread1 extends Thread public voia run() for(int i=0;i10;i+) System.out.println(Thread.currentThread().getName()+”:”+i); public class TestThread1 public static void main(String args
11、) SubThread1 st1= new SubTread1(); st1.setName(“子线程1”); st1.start(); Thread.currentThread().setName(“主线程”); for(int i=0;i10;i+) System.out.println(Thread.crrentThread().getName()+”:”+i); if(i=20) /当i等于20的时候,当前线程(主线程)停止运行,并运行线 程st1,当st1运行结束,继续运行主线程 */ try st1.join(); catch(InterrupterExcption e) e.pr
12、intstackTrace(); System.out.println(st1.isAlive(); /判断线程st1是否还存活(当前结果是否); 例子5:sleep(long a),需要抛try catch 异常class SubThread1 extends Thread public voia run() for(int i=0;i10;i+) System.out.println(Thread.currentThread().getName()+”:”+i); try Thread.sleep(1000); /当线程没执行一次for循环睡眠1000毫秒 catch(Interrupte
13、dException e) e.printStackTrace(); public class TestThread1 public static void main(String args) SubThread1 st1= new SubTread1(); st1.setName(“线程1”); st2.setName(“线程2”); st1.start(); st2.start(); 例子6:设置优先级class SubThread1 extends Thread public voia run() for(int i=0;i10;i+) System.out.println(Thread
14、.currentThread().getName()+”:”+i); / 调用当前线程的名字,当前线程是st1 public class TestThread1 public static void main(String args) SubThread1 st1= new SubTread1(); st1.setPriority(Thread.MAX_PRIORITY); /设置线程st1的优先级为最大,即10 st1.setName(“子线程1”); st1.start(); Thread.currentThread().setName(“主线程”); for(int i=0;i10;i+
15、) System.out.println(Thread.crrentThread().getName()+”:”+i); 2第二种创建:实现Runnable接口 class Thread2 implements Runnable / 1.创建一个类实现Runnable接口 public void run() / 2.实现接口的抽象方法run方法 /子线程执行的代码 for(int i=1;i=100;i+) System.out.println(Thread.currentThread().getName+”:”+i); public class TestThread2 public stat
16、ic void main(String args) Thread2 th = new Thread2(); / 3.创建一个Runnable接口的实现类的对象 Thread thread1 = new Thread(th,”线程1”); / 4.创建一个Thread类的对象,并将Runnable实现类的对象加入到构造器中, 此时创建的Thread对象即为一个线程 / Thread thread2 = new Thread( th,”线程2”); /启动线程;过程:执行Thread对象生成时构造器形参的对象的run方法 Thread thread3 = new Thread( th,”线程3”)
17、; thread1.start(); / 5.调用Thread的start方法,启动线程 thread2.start(); thread3.start(); (2)线程创建方法之继成和实现的区别1联系:public class Thread implements Runnable2哪种方式好?为什么 实现优于继承 原因:1.避免了java单继承的局限性 2.如果多线程操作同一份资源(不过可能存在一些线程安全问题),更适合使用实现的方式3.线程安全问题(1)存在的原因 由于一个线程在操作共享数据的过程中,未完毕的情况下,另外的线程也参与进来,导致共享数据存在了安全问题(2)如何解决:1解决原理:
18、必须让一个线程操作完毕共享数据后,其他线程才有机会操作共享数据 2 java中解决线程安全的方式:线程同步机制。(以下两种方法解决) 1方法一:同步代码块1语法格式: synchronized(同步监视器) (读音:sing克瑞耐zed) / 需要被同步的代码(即为操作共享数据的代码, 这里需要特别注意) 2使用场景和锁的使用: 1.共享数据多线程共同操作一个数据(变量) 2.同步监视器(即锁):由任意一个类的对象来充当(不过在所有线程中,本对象必须只能 有一个),哪个线程获得此监视器,谁就执行大括号里被同步的代码。俗称:锁。要求所有 线程必须使用同一把锁。(例子如下)运行结果如下:PS:实现
19、this,继承慎用:在通过实现Runnable创建线程时,可以用this作为同步监视器,但是通过继承Thread类来创建线程,慎用this(如果创建的类对象只有一个时可以用,不然不可以用)2方法二:同步方法(例子如下图)过程:将操作共享数据的方法声明为synchronized。此方法为同步方法,能够保证其中一个线程执行此方法时,其他线程在外等待直至此线程执行完此方法。同步方法的锁是:当前this。注意:不管是同步代码块还是同步方法,synchronized所包含的内容必须是共享数据部分,不能多也不能上,比如上述例子,多了sleep一段代码块运行时就只执行线程1了。4. 线程的生命周期线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止 补充:1.wait阻塞,sleep、yield不阻塞:调用wait方法可以让线程进入阻塞状态。注意sleep和yield方法不能让线程进入阻塞状态。/本句看法有疑问2.线程安全问题总结:线程在调用run方法运行的时候,当别的线程过来抢占CUP执行权的时候,原来的线程可能程序还未执行完,并进入就绪状态,这就导致了线程安全问题。5.线程的通信同步锁ps: 每个java程序都有一个隐含的主线程:main方法 和一个垃圾回收线程(守护线程,不会显现出来,但在后台运行)
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2