java030:线程的基本控制,线程同步协调

一,Suspend():挂起,不抢占CPU了,相当于阻塞了 ----- 被wait替代
Resume():唤醒 ,重新抢占CPU----- 被notify替代
在这里插入图片描述
运行结果:先输出1,然后回车唤醒一次,输出一次,直到输出完毕
注意: Suspend(),resume()这两个方法过时,并且禁止使用。
Suspend()挂起的线程不安全,而且容易出现死锁,一旦挂起,不会释放锁
二, Join():加入,当一个线程从中间加入进来后就会独享cpu,会把自己所有的代码执行完毕之后才让出cpu让其他线程执行

package 多线程;
import java.io.IOException;
class A implements Runnable{
	private Thread b;//A关联B获得B的线程
	public A(Thread b){//构造器调用B的构造器
		this.b=b;
	}
	int i;
	public void run() {
		for (i = 1; i <=10; i++) {
			if(i==3){//当A输出到3的时候,B加进来,一口气输出完
				try {
					b.join();//此处的异常只能捕获,因为join的父类的异常没有抛
					//所以子类也不能抛
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+"   "+i);
		}
	}
}
class B implements Runnable{

	public void run() {
		for (int i = 1; i <=10; i++) {
			System.out.println(Thread.currentThread().getName()+"   "+i);
		}
	}
}
public class Test {
	public static void main(String[] args) throws IOException {
		//新建状态
		B b=new B();
		Thread t2=new Thread(b,"我是b,我加入进来");
		A a=new A(t2);
		Thread t1=new Thread(a,"我是a");
		//运行状态
		t1.start();
		t2.start();
	}
}

运行结果为:
在这里插入图片描述
join的另一个应用:如下图:当我们以为只有一条线程时,就忽略了main也是一条线程,原本会输出8,但是当18代表的线程加入进来后,不管它睡眠多久,8也得等着。
在这里插入图片描述
三,Sleep():睡眠
见上一篇
四,yield():让步,针对同一级别的其它线程,当前线程会让出cpu再和其它同一级别的线程重新抢占cpu。注意是让出之后再重新抢,不是让给它,只是给了它一次抢占CPU的机会。
在这里插入图片描述
上程序的意思是:不管是谁输出一次,让出CPU重新抢,结果如下:
在这里插入图片描述
五,线程的同步,协调

同步就是线程安全,就是保证任务块里面的所有代码是一个原子性,不可分割!不能只输出到一半就让其他代码抢走线程,从而导致数据不安全
每一个对象都是一把锁,这个锁在同一时刻只能被其中一个线程所具有,如果多个线程竞争同一把锁,那么就要等待
比如这个程序:上了锁之后即使A的线程被B抢走,B也不能立即执行,而是等到A把它里面的程序输出完整后,释放锁。B拿到锁后执行程序,同时上锁,如若A再抢到线程,也要等到B程序输出完整后才可以执行
在这里插入图片描述
就像这样,不可能说执行到中间让其他程序抢走线程后就直接中断,而是会完整输出,在释放锁,让其他程序执行。前提是两个程序要用同一把锁,如果不上锁或者上两把锁,输出也不会完整,数据也不安全。

package 多线程;
import java.io.IOException;
class A implements Runnable{
	Object lock;
	public A(Object lock){
		this.lock=lock;
	}
	public void run() {
		while(true){
			//上锁
			synchronized (lock) {
				System.out.println("1111111111111");
				System.out.println("2222222222222");
				System.out.println("3333333333333");
				System.out.println("4444444444444");
			}
			//释放锁
		}
	}
}
class B implements Runnable{
	Object lock;
	public B(Object lock){
		this.lock=lock;
	}
	public void run() {
		//加同步块,锁lock对象
		while(true){
		synchronized (lock) {
				System.out.println("aaaaaaaaaaaaaaaaaa");
				System.out.println("bbbbbbbbbbbbbbbbbb");
				System.out.println("cccccccccccccccccc");
				System.out.println("dddddddddddddddddd");
			}
			//释放锁
		}
	}
}
public class Test {
	public static void main(String[] args) throws IOException, InterruptedException {
		Object obj=new Object();
		A a=new A(obj);
		B b=new B(obj);
		Thread t1=new Thread(a);
		Thread t2=new Thread(b);
		t1.start();
		t2.start();
	}
}	
	

以上就是现场的同步,确保了线程的安全性。
协调,在同步的基础上协调工作,就好比走路,不管是先迈出左脚还是右脚,总之走路要一左一右,才是协调。
如下图,在锁里加入obj.wait(),表示输出完了之后等待。
此时出现的异常要捕获,以为他的父类没有抛异常
在这里插入图片描述
如果两条线程都加了obj.wait;则会有下面的结果:
在这里插入图片描述
两个线程各输出一次,然后等待,但是程序依然没有结束。所以为了让线程继续下去,我们需要在等待之前唤醒对方线程。
注意:不能写成这样,如果这样,在线程等待的时候,不能执行后面的程序,所以也就不能唤醒对方线程,要把obj.notify写在obj.wait的前面。

obj.wait();
obj.notify();

所以代码如下:

class AA implements Runnable{
	Object obj;
	public AA(Object obj){
		this.obj=obj;
	}
		public void run() {
			
			while(true){
				synchronized (obj) {
					System.out.println("AAAAA");
					System.out.println("BBBBB");
					System.out.println("CCCCC");
					System.out.println("DDDDD");
					try {
						//唤醒正在等待的对方线程
						obj.notify();
						//该线程处于等待状态,不抢占cpu,同时释放锁
						obj.wait();//异常捕获,因为父类没有抛异常
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		}}
	class BB implements Runnable{
		Object obj;
		public BB(Object obj){
			this.obj=obj;
		}
		public void run() {
			
			while(true){
				synchronized (obj) {
					System.out.println("11111");
					System.out.println("22222");
					System.out.println("33333");
					System.out.println("44444");
					try {
						obj.notify();
						obj.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}}
public class Test {
	
	public static void main(String[] args) {
		Object obj=new Object();
		AA a=new AA(obj);
		BB b=new BB(obj);
		Thread t1=new Thread(a);
		Thread t2=new Thread(b);
		t1.start();
		t2.start();
	}

}

输出结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值