黑马程序员——Java之Thread类

来源:互联网 发布:大家都用阿里云做什么 编辑:程序博客网 时间:2024/04/30 15:01

———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

多线程:
* 进程:是一个正在执行中的程序,每个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元
* 线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行
* 一个进程中至少有一个线程
*JVM启动时,会有一个进程java.exe,该进程中至少有一个线程负责java程序的执行,而且这个进程运行的代码存在于main方法中,该线程称之为主线程
* 扩展:其实JVM启动时,不止一个线程,还有负责垃圾回收机制的线程
*多线程存在的意义:
* 提高程序运行的效率
*多线程的创建方式一:
* (1)自定义一个类并继承Thread类
* (2)重写Thread类中的run();方法
* 将自定义的代码放在run()方法中,让线程运行
* (3)创建自定义类的对象(新线程)
* (4)调用Thread类中的start();方法,开启线程
* 开启新线程,并执行run()方法里面存放的代码
创建实例:

//继承的方式创建多线程class MyThreadOne extends Thread{    public static int tick=100;    public MyThreadOne(String name) {        super(name);    }    public  void run(){        while(true){            synchronized (MyThreadOne.class) {            if(tick>0){                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(Thread.currentThread().getName()+"stick"+"\t"+tick--);             }            }        }    }}public class MoreThread{    public static void main(String [] agrs){        MyThreadOne myThreadOne_01=new MyThreadOne("One+++");        MyThreadOne myThreadOne_02=new MyThreadOne("Two+++");        MyThreadOne myThreadOne_03=new MyThreadOne("Three+++");        MyThreadOne myThreadOne_04=new MyThreadOne("Four+++");        MyThreadOne myThreadOne_05=new MyThreadOne("Five+++");        myThreadOne_01.start();        myThreadOne_02.start();        myThreadOne_03.start();        myThreadOne_04.start();        myThreadOne_05.start();

*多线程的创建方式二:
* (1)定义一个类并实现Runnable接口
* (2)重写Runnable接口中的run();方法
* 将线程要运行的代码存放在run()方法中
* (3)通过Thread类创建线程对象
* (4)将Runnable接口的子类对象作为实际参数传递给Thread类的构造方法
* 因为重写的run()方法所属于Runnable接口的子类对象,所以要让线程去执行指定对象的run()方法,就必须在Thread类的构造函数指明run()方法所在的对象
* (5)调用Thread类的start();方法,开启线程,并调用Runnable接口子类的run()方法
创建实例:

//实现接口的方式创建多线程class MyThreadTwo  implements Runnable{      public int  tick=100;      public void run(){          while(true){              synchronized (MyThreadTwo.class) {              if(tick>0){                  try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }                  System.out.println(Thread.currentThread().getName()+"---stick"+"\t"+tick--);              }            }          }      }}public class MoreThread{    public static void main(String [] agrs){        MyThreadTwo myThreadTwo=new MyThreadTwo();        Thread thread1=new Thread(myThreadTwo);        thread1.setName("ONE");        Thread thread2=new Thread(myThreadTwo);        thread2.setName("TWO");        Thread thread3=new Thread(myThreadTwo);        thread3.setName("THREE");        thread1.start();        thread2.start();        thread3.start();    }}

*实现方式和继承方式有什么区别?
* (1)实现方式的好处:避免了单继承的局限性(一旦一个类已经继承了另一个类,并且包含有需要被多线程执行的代码,那么就不能再继承Thread类了,这是只能用实现Runnable接口的方式实现)
* (2)在定义线程时,建议使用实现的方式
* (3)继承Thread类:线程代码存放在Thread类的子类的run()方法中
* (4)实现Runnable接口:线程代码存放在Runnable接口的run()方法中
*局部变量在每一个线程区域中都有独立的一份
*为什么要重写run();方法?
* Thread类是用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该存储功能就是run()方法,也就是说Thread类中的run()方法是用于存储线程要运行的代码
*线程的五种状态:
* (1)被创建状态
* (2)运行状态:此状态线程既有执行资格,又有执行权。需要start()开启线程
* (3)阻塞状态:此状态线程只有执行资格,没有执行权。
* (4)冻结状态:此状态线程既没有执行资格,也没有执行权。a:sleep(long mi)睡眠状态,时间一到自动转到阻塞状态;b:wait()等待状态,需要用notify()唤醒
* (5)消亡状态:a:可以由stop()函数触发;b:线程的run()方法运行结束后也是此状态
*线程都有自己的默认名称:Thread-编号 ,该编号从何0开始
* static Thread currentThread()方法可以用来获取当前线程对象
* getName():获取线程的名称
* setName()和构造函数:可以设置线程的名称
*线程安全问题:
* (1)问题的原因:
* 当多个线程在操作多条语句中的共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程就参与进来执行,导致共享数据出现错误
* (2)解决方法:
* 对多条操作共享数据的语句,只能让一个线程都执行完,因此在执行过程中,其他线程不可以参与执行
* (3)java对于多线程在安全问题提供了专业的解决方式
* 同步代码块解决多线程的安全问题
* synchronized(任意一个对象){
* 需要同步的代码
* }
* 同步函数解决多线程安全问题
* public synchronized void add(){
*
* }
* synchronized关键字不能修饰run()方法
* 同步函数的锁是什么?
* (1)函数需要被对象调用,那么函数都有一个所属对象的引用,就是this,所以同步函数的锁就是this
* (2)如果同步函数被static修饰,同步函数使用的锁是什么呢?
* a:通过验证,发现此时静态同步函数的锁不再是this了,因为静态方法中也不可以定义this
* b:静态进内存时,内存中没有本类的对象,但是一定有该类对应的字节码文件对象(类名.class),该对象的类型时Class
* c:所以静态同步方法中,使用的锁是该方法所在类的字节码文件对象,即类名.class对象
*
*对象如同锁,持有锁的线程才可以在同步中执行,没有锁的线程即使获取了cpu的执行权,也进不去,因为没有获得锁
* 同步的前提:
* (1)必须要有两个或者两个以上的线程
* (2)必须是多个线程使用同一个锁
* 必须保证同步代码块中只能有一个线程在运行
*同步的好处:解决了多线程的安全问题
*同步的弊端:多线程需要判断,较为消耗资源

0 0