JAVA多线程

来源:互联网 发布:同花顺看盘软件 编辑:程序博客网 时间:2024/06/03 14:30

多线程:

多线程创建的两种方式

extents Thread

implement Runnable

两种方法区别

在使用中建议使用第二种方法 implement Runnable 因为这种方法可以一个类中实现多个接口,避免了单继承的局限性

 

start() 和run()的区别与联系

run()是在jvm中创建一个方法,并不会自己调用并自己执行。

start()方法在执行的时候,首先会检查对象中有没有run方法,有的话会启动线程,调用run方法

 

暂停线程运行的两种方法

wait();  使线程进行休眼状态,如果不被唤醒,则该线程一直处于休眼状态。唤醒调用的方法是Object.notify();或Object.notifyAll();唤醒此对象中已休眼的所有的线程

sleep(); 使线程进行休眼状态,休眼时间到(并获得操作权限以后)会自动执行

 

多线程执行流程图

使用runnable接口实现多线程的步骤

1、定义类实现runnable接口

2、覆盖run()方法

3、通过thread建议线程对象

4、将Runnable接口的子类对象作为实际参数传给thread的构靠

5、调用thread的start();开启线程并调用Runnable的run方法

 

使用同步块 检查多线程是否安全的步骤

1、看一下哪些是共享数据

2、看一下哪个部分是多线程运行的方法

3、明确多线程中哪些语句是操作共享数据的

 

 

多线程同步的死锁与预防死锁

1、 必须是两个以上的线程

2、要同步的线程使用同一对象

 

 多线程睡眠与唤醒机制(睡眠与唤醒的方法必须在同步代码块或方法中执行)

睡眠方法    对象.wait();  将本线程置与睡眠状态 除非别的线程执行notify()或notifyAll()方法,否则不能解除睡眠状态;睡眠状态的时候会放弃的执行权,将对象锁交给别人

唤醒方法 

对象.notify();  对该对象下面的单个线程唤醒(当前线程不能是睡眠状态);如果该对象下面有多个睡眠的线程,则唤醒一个线程池中睡眠的第一个线程  

对象.notifyAll();对该对象下面的所有线程唤醒(当前线程不能是睡眠状态)  唤醒之后不会重头开始执行线程,只会从被唤醒的地方开始往下执行

 注意:

要同时满足以下条件:

1、在run()方法中使用循环,使用每次睡眠被唤醒换重装执行循环操作

2、加判断标签,控制线程结束

 

程序中调用方法停止线程(生产者--消费者)

//资源类(人类),拥有数据的执行权,所以拥有对数据的处理方法  

其中production()因为要被多线程调用,所以加synchronized同步方法  因为不是双线程,而是多线程,为了避免线程全部被休眠,所以使用notifyAll()方法

[java] view plaincopyprint?
  1. class Persons {  
  2.   
  3.     private String username;  
  4.     private String password;  
  5.     boolean flag = false;  
  6.   
  7.     public void set(String username, String password) {  
  8.   
  9.         this.username = username;  
  10.         this.password = password;  
  11.     }  
  12.   
  13.     int x = 0;  
  14.   
  15.     public synchronized void production() {  
  16.   
  17.         if (flag) {  
  18.             try {  
  19.                 wait();  
  20.             } catch (InterruptedException e) {  
  21.                 e.printStackTrace();  
  22.             }  
  23.         } else {  
  24.   
  25.             if (x == 0) {  
  26.                 this.username = "wxq----------------------------";  
  27.                 this.password = "wxq-password-------------------";  
  28.             } else {  
  29.                 this.username = "ccc--------------";  
  30.                 this.password = "ccc-password-----";  
  31.   
  32.             }  
  33.             x = (x + 1) % 2;  
  34.             flag = true;  
  35.             notifyAll();  
  36.   
  37.         }  
  38.     }  
  39.   
  40.     public synchronized void comsumption() {  
  41.   
  42.         if (flag) {  
  43.             System.out.println("username=" + username);  
  44.             System.out.println("password=" + password);  
  45.             flag = false;  
  46.             notifyAll();  
  47.         } else {  
  48.             try {  
  49.                 wait();  
  50.             } catch (InterruptedException e) {  
  51.                 e.printStackTrace();  
  52.             }  
  53.   
  54.         }  
  55.   
  56.     }  
class Persons {private String username;private String password;boolean flag = false;public void set(String username, String password) {this.username = username;this.password = password;}int x = 0;public synchronized void production() {if (flag) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}} else {if (x == 0) {this.username = "wxq----------------------------";this.password = "wxq-password-------------------";} else {this.username = "ccc--------------";this.password = "ccc-password-----";}x = (x + 1) % 2;flag = true;notifyAll();}}public synchronized void comsumption() {if (flag) {System.out.println("username=" + username);System.out.println("password=" + password);flag = false;notifyAll();} else {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}


多线程操作类生产者(Production)   其中changeFlag()方法用于控制线程的结束权

[java] view plaincopyprint?
  1. class Production implements Runnable {  
  2.   
  3.     Persons p;  
  4.   
  5.     Production(Persons p) {  
  6.         this.p = p;  
  7.   
  8.     }  
  9.   
  10.     boolean flag = true;  
  11.   
  12.     public void run() {  
  13.   
  14.         while (flag) {  
  15.             p.production();  
  16.         }  
  17.   
  18.     }  
  19.   
  20.     public void changeFlag() {  
  21.   
  22.         this.flag = false;  
  23.     }  
  24.   
  25. }  
class Production implements Runnable {Persons p;Production(Persons p) {this.p = p;}boolean flag = true;public void run() {while (flag) {p.production();}}public void changeFlag() {this.flag = false;}}


多线程操作类消费者(Comsumption) 其中changeFlag()方法用于控制线程的结束权

[java] view plaincopyprint?
  1. class Comsumption implements Runnable {  
  2.   
  3.     Persons p;  
  4.   
  5.     Comsumption(Persons p) {  
  6.         this.p = p;  
  7.   
  8.     }  
  9.   
  10.     boolean flag = true;  
  11.   
  12.     public void run() {  
  13.         while (flag) {  
  14.             p.comsumption();  
  15.         }  
  16.     }  
  17.   
  18.     public void changeFlag() {  
  19.   
  20.         this.flag = false;  
  21.     }  
  22. }  
class Comsumption implements Runnable {Persons p;Comsumption(Persons p) {this.p = p;}boolean flag = true;public void run() {while (flag) {p.comsumption();}}public void changeFlag() {this.flag = false;}}


 调用者类

[java] view plaincopyprint?
  1. public class Demo2 {  
  2.     public static void main(String[] args) {  
  3.   
  4.         Persons p = new Persons();  
  5.         Production pro = new Production(p);  
  6.         Comsumption com = new Comsumption(p);  
  7.         Thread t1 = new Thread(pro);  
  8.         Thread t2 = new Thread(pro);  
  9.         Thread t3 = new Thread(com);  
  10.         Thread t4 = new Thread(com);  
  11.         t1.start();  
  12.         t2.start();  
  13.         t3.start();  
  14.         t4.start();  
  15.   
  16.         try {  
  17.             Thread.sleep(4000);  
  18.             pro.changeFlag();  
  19.             com.changeFlag();  
  20.         } catch (InterruptedException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.   
  24.     }  
  25. }  
public class Demo2 {public static void main(String[] args) {Persons p = new Persons();Production pro = new Production(p);Comsumption com = new Comsumption(p);Thread t1 = new Thread(pro);Thread t2 = new Thread(pro);Thread t3 = new Thread(com);Thread t4 = new Thread(com);t1.start();t2.start();t3.start();t4.start();try {Thread.sleep(4000);pro.changeFlag();com.changeFlag();} catch (InterruptedException e) {e.printStackTrace();}}}


 

守护线程

setDeamon() 将一定线程定义为守护线程的方法

使用场景:

守护线程也可以称为后台线程,数据依赖于前台线程,如果前台线程结束,则守护线程自动结束(当程序中执行的所有线程都为守护线程的时候,JVM退出)

使用注意:定义守护线程必须在该线程启动前调用他

 

 线程停止的方法

1、stop();此方法已过时

2、在线程的循环当中添加标签(判断是否继续循环,如果想停止线程,则在外部调用线程中改变标签的方法)

3、中断线程interrupt();  当程序没有方法法回到执行状态,使用中断线程将正在休眠的线程中断休眠状态,并抛出 InterruptedException异常供处理;

 

 线程join()  

等待该线程终止

 当一个主线程中,执行了子线程的join();方法的时候,便会释放执行权(不和子线程抢资源,也就是终止自己),等子线程执行完了再执行其本身。

主要作用在于,主线 程需要子线程的数据,那么等子线程执行完,然后再执行自己线程,获取子线程的数据

 

线程yield()

将执行权交到别的线程(非冻结)

 等别的线程释放执行权的时候自己再执行

 

线程优先级setPriority 

可以设定的几个值有MAX_PRIORITY  MIN_PRIORITY    NORM_PRIORITY 初始值为5

设置优先级,可以使CPU分配执行次数多一点,并不会把所有的执行权抢过来

原创粉丝点击