多线程之间实现通讯

1.多线程之间通讯

多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。

//共享资源实体类
​class Person {
	private String name;
	private String sex;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
}
//线程一
class T1 implements Runnable {
	
	private Person p;
	
	public T1(Person p) {
		this.p = p;
	}

	public void run() {
		boolean b = true;
		while(true) {
			synchronized (p) {
				if(b) {
					p.setName("wenlong");
					p.setSex("男");
					b = false;
				}else {
					p.setName("bug");
					p.setSex("男");
					b = true;
				}
			}
		}
	}
}
//线程二
class T2 implements Runnable {
	
	private Person p;
	
	public T2(Person p) {
		this.p = p;
	}
	public void run() {
		while(true) {
			synchronized (p) {
				System.out.println(p.getName() + p.getSex());
			}
		}
	}
	
}
//主函数
public class ThreadDemo {
	
	public static void main(String[] args) {
		Person p = new Person();
		Thread tt = new Thread(new T1(p));
		Thread ttt = new Thread(new T2(p));
		
		tt.start();
		ttt.start();
	}
}
//运行结果
wenlong男
wenlong男
wenlong男
wenlong男
wenlong男
wenlong男
wenlong男
wenlong男
bug男
bug男
bug男
bug男
bug男
bug男

wait(),notify,notifyAll()方法

wait(),notify(),notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。

这个方法最终调用的都是jvm级的natie方法,随着jvm运行平台的不同可能有些许差异。

如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。

如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。

如果对象调用了notifyall方法就会通知所有等待这个对象控制权的线程继续运行。

注意:一定要在线程同步中使用,并且是同一个锁的资源。

public class ThreadDemo {
	
	public static void main(String[] args) {
		Person p = new Person();
		Thread tt = new Thread(new T1(p));
		Thread ttt = new Thread(new T2(p));
		
		tt.start();
		ttt.start();
	}
}

class Person {
	private String name;
	private String sex;
	private boolean bool = false;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public boolean isBool() {
		return bool;
	}
	public void setBool(boolean bool) {
		this.bool = bool;
	}
	
}

class T1 implements Runnable {
	
	private Person p;
	
	public T1(Person p) {
		this.p = p;
	}

	public void run() {
		boolean b = true;
		while(true) {
			synchronized (p) {
				if(p.isBool()) {
					try {
						p.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				if(b) {
					p.setName("wenlong");
					p.setSex("男");
					b = false;
				}else {
					p.setName("bug");
					p.setSex("男");
					b = true;
				}
				p.setBool(true);
				p.notify();
			}
		}
	}
}

class T2 implements Runnable {
	
	private Person p;
	
	public T2(Person p) {
		this.p = p;
	}
	public void run() {
		while(true) {
			synchronized (p) {
				if(!p.isBool()) {
					try {
						p.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(p.getName() + p.getSex());
				p.setBool(false);
				p.notify();
			}
		}
	}
	
}
//运行结果
bug男
wenlong男
bug男
wenlong男
bug男
wenlong男
bug男
wenlong男
bug男
wenlong男

wait与sleep区别

sleep方法是属于Thread类中的,而wait()方法,则是属于object类中的

sleep()方法导致了程序暂停指定的时间,让出cpu该其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的时候,线程不会释放对象锁。

而调用wait方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

 

JDK1.5-Lock

在 jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock 接口提供了与 synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。

Lock lock  = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
  lock.ublock();
}

Lock接口与synchronized关键字的区别

Lock接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。

Lock接口能被中断地获取锁与synchronized不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。

Lock接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。

condition用法

condition的功能类似于在传统的线程技术中的Object.wait()和Object.notify()的功能

Condition condition = lock.newCondition();
condition.await();
condition.signal()

ThreadLoca

threadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。

当使用ThreadLocal维护变量时,ThreadLocal为每个使用变量的线程提供独立的变量副本,所有每一线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本。

ThreadLoca实现原理

ThreadLoca通过map集合

map.put("当前线程",值);

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值