JAVA多线程

多线程:

多线程创建的两种方式

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()方法

  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()方法用于控制线程的结束权

  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()方法用于控制线程的结束权

  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;
	}
}


 调用者类

  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分配执行次数多一点,并不会把所有的执行权抢过来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值