【掌握的】
1.两种方式创建线程:(继承,实现)
2.继承和实现的区分
3.线程的生命周期
4.不同状态下,所对应的方法。【通过哪些方法,可以让线程达到某个状态。】
5.同步代码块,同步方法。
----------------------
1.学习多线程的原因?
生活中:
程序: 一个完整的功能代码。(方法,没有被运行)
进程: 一个完整的功能代码。(方法,被运行)
线程: 进程包含线程。
好处:提高代码的执行效率。总是有一些功能是需要同时执行的,那就需要多线程。
2.主线程: -----执行main方法里的代码。
普通线程 ------run 方法里的代码。
3.完成线程的步骤:
A. 编写线程类:(1.通过继承)
B. 重写run方法:
C. 创建线程对象,调用start方法,开启线程。
补充:
(1) 线程对象.run(); 没有开启线程,只是在调用线程对象的run()方法。 线程对象.start(); 线程开启的标志,自动调用run()方法 (2) 调用start()方法就立刻执行run()方法吗?
线程对象.start(); ----当前线程所处的状态是“就绪状态”
真正执行run();----当前线程所处的状态是“运行状态”
----“就绪状态” 和“运行状态” 之间,间隔多久,不清楚。
(3)线程 【默认命】和【指定名】。
普通线程的默认名:Thread-变量 ----变量static的,从0开始计数
主线程默认名:main
// private String name; //1.接收外界传入的参数,完成线程名。 // public Thread1(String name){ // this.name=name; // } public Thread1(String name){//2.调用父类有参,完成线程命名。 super(name); }
public void run() { // Thread.currentThread().setName(name); for (int i = 1; i <= 10; i++) { System.out.println (Thread.currentThread().getName()+"--->"+i); } }
【2.通过实现完成线程】 A.编写线程类:
B.。重写run()方法
C。创建线程实现类对象,
创建线程对象,
线程对象调用方法,开启线程。
补充: (1.) Thread 实现 Runnable接口 (2.)Thread th
Thread2 th2 都实现Runnable接口 ,在th .start();---th2.run()被执行。【代理模式】
(3.)继承方式, VS 实现方式 哪种线程类更好?
实现方式 好:
1.可以多实现
2.数据共享。
【例子:3个窗口同时销售5张火车票】 【继承方式:】public class ThreadPiao extends Thread { private int piao=5; public void run() { for(int i=1;i<=100;i++){ if(piao>0){ System.out.println (Thread.currentThread().getName()+"---"+piao--); } } }} 【测试代码】 new ThreadPiao().start(); new ThreadPiao().start(); new ThreadPiao().start();
【实现方式】public class ThreadP implements Runnable {
private int piao=5; public void run() { for(int i=1;i<=100;i++){ if(piao>0){ System.out.println (Thread.currentThread().getName()+"---"+piao--); } } }
} 【测试代码】 ThreadP tp=new ThreadP(); new Thread(tp).start(); new Thread(tp).start(); new Thread(tp).start();
问题:继承方式,可不可以只new 1个线程对象,然后调用3次start()方法?
4.线程状态/生命周期: A.新生状态: new 线程类(); B.就绪状态: start(); 【有被执行的资格,但是还没有被cpu调度;队列】 C.运行状态: run(); D.阻塞状态: sleep(): 礼让 yi (); 强制 join(); D.死亡状态:A。正常线程结束 B。发生异常,产生异常对象,没有被截获。
C。线程自身调用了Stop()。---不被使用
4.1新生状态: 创建线程对象,可以调用无参,有参(给线程命名) ---可以获得到的信息:
1.获得线程对象。名字 Thread.currentThread().getName()
2.设置或获得当前线程的优先级: th.setPriority(9); System.out.println("线程优先级最大是:"+Thread.MAX_PRIORITY); System.out.println("线程优先级最大是:"+Thread.MIN_PRIORITY); System.out.println("th1的线程优先级是:"+th.getPriority()); 4.2就绪状态:
是否处于就绪状态:Thread.currentThread().isAlive() 4.3运行状态:
程序执行run();【有被执行的资格,同时也被CPU调度。但是至于什么时间被执行的,不清楚】
4.4阻塞状态:
【线程强制执行:join()】
for (int i = 1; i <=10; i++) { if(i==3){ try { th.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"--"+i); } 说明:普通线程强制抢占了cpu资源。
主线程:由原来的运行状态----》阻塞状态---就绪状态---运行状态
普通线程:直接运行结束。
使用场合:线程有明确的【完成先后顺序】。
【线程休眠:sleep()】
for (int i = 1; i <=10; i++) { if(i==3){ Thread.sleep(3000);//单位是毫秒 } System.out.println(Thread.currentThread().getName()+"--"+i); }
说明:(1)当前线程休眠:由原来的运行状态----》阻塞状态---就绪状态---运行状态 ---休眠时间结束,进入到就绪状态,等待cpu调度。
(2)中途阻止休眠:(了解) 【例子:】 终止休眠: 1. th.interrupt(); 2. 在异常捕获的时候,出现return。
【线程礼让:】
for (int i = 0; i < 10; i++) { if(i==3){ Thread.yield(); System.out.println("线程礼让一次"); } System.out.println(i); } 说明:让出当前这次cpu资源:线程状态不阻塞---直接进行就绪状态--运行状态。
5.线程安全:
多线程同时操作数据资源,会出现数据不正确。所需线程同步。
第一种方式:同步代码块 ---使用在线程中。
public void run() { for (int i = 1; i <=100; i++) { synchronized(this){ if(piao>0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--"+piao--); } } } }
第二种方式:同步方法: public void run() { for (int i = 1; i <=100; i++) { maip(); } }
public synchronized void maip(){ if(piao>0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--"+piao--); } }
转载于:https://www.cnblogs.com/zhuhuibiao/p/9313876.html