首页 > 代码库 > 7、多线程

7、多线程

1、创建多线程

方法一:
          1、自定义继承自Thread的子类;
          2、重写run(),自定义代码添加进去
          3、创建Thead子类对象,并调用start()方法开启线程(线程一旦开启,就会执行run方法,不要直接调用run()方法)
 
方法二:(推荐使用)Java是单继承,多实现(接口)的
          1、自定义类实现Runnable接口
          2、实现Runnable接口的run(),把自定义线程的任务定义在run()中  
          3、创建Runnable实现类对象,并创建Thread类的对象,把Runnable对象作为实参传递
          4、调用Thread对象的start方法开启线程
 
Runnable实现类的对象并不是一个线程对象,只是实现了Runnable接口的对象,只有Thread及其子类才是
Runnable实现类的对象作为实参传递给Thread对象的作用是把Runnable实现类的对象的run方法作为线程的任务代码执行
此种方法下可以不用static修饰来保证共享同一资源,传入的是同一个Runnable类实现对象已经保证
技术分享

2、线程常用方法

(1)

Thread(String name);  // 初始化线程名称,Thread的run方法没有抛出异常类型,所以子类也不能抛出,只能捕获

(2)

getName();  // 返回线程的名称

(3)

setName(String name);  // 改变线程的名称

(4)

sleep(long millis);  // 静态方法,哪个线程执行就是哪个线程睡眠

(5)

getPriority();  // 线程的优先级默认是5

(6)

setPriority(int newPriority);  // 优先级1~10

(7)

currentThread();  // 返回当前执行对象的引用,哪个线程执行了就返回哪个线程的对象

非静态成员变量在每个对象中都会维护一份数据

 

3、线程安全

多个对象共享同一资源

解决方案:线程同步
      方式一:同步代码块(推荐使用)
      synchronized(锁对象){同步代码}
      锁对象可以是任一静态唯一的对象  static Object o = new Object(); 同步代码块中调用sleep不会释放锁对象
      同步机制使用了对象中的状态作为锁的标志(state = 0(开))
      方式二:同步函数
      用synchronized修饰一个函数(public static synchronized void getMoney())
      非静态同步函数的锁对象是this对象;静态同步函数的锁对象是当前函数所属类的字节码文件(class对象)
      同步函数的锁对象是固定的,不能任意指定
 
静态函数所属的类的字节码文件BankThread.class,字节码对象是唯一的

技术分享

 

4、死锁

同步机制解决了线程安全问题,但同时引发了死锁
     
存在的条件:
1、存在两个或两个以上的线程
2、存在两个或者两个以上的共享资源
 
无解决方案,尽量避免

 5、线程通讯

 一个线程完成了任务时,通知另一个线程

 
生产者与消费者问题
          
wait();   // 进入(锁对象为标识符的线程池中)等待状态,必须被其他线程调用notify才能唤醒,释放锁对象
notify();  // 唤醒(线程池中某个)等待线程,先等待先唤醒 
notifyAll();

注意事项:

1、都是属于Object对象(锁对象是任意对象)
2、必须在同步代码块或者同步函数中才能使用(同步代码块中才有锁对象,必须由锁对象调用)
3、必须要由锁对象调用(锁对象保证唤醒或者等待线同一标识符的程池中其中一个线程)
 
 
线程的停止
方法1、一般通过一个标志变量控制
方法2、interrupt(),强制清除等待状态,该线程接收到interruptExecption异常
 
守护线程(后台线程)
一个进程中只剩下守护线程,守护线程也会死亡
isDaemon():判断是否守护线程
setDaemon():设置守护线程,线程默认都不是守护线程
 
join():加入新线程,新线程执行完后再执行原有线程

7、多线程