JAVA 线程间通信(一)安全问题

线程间通信

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

代码示例:两个线程同时操作性别和姓名出现安全隐患

package contact;

class Res
{
	String name;
	String sex;
}

class Input implements Runnable
{
	private Res r; 
	Input(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		int x=0;
		while(true)
		{
			if(x==0)
		{
			r.name="mike";
			r.sex="man";
		}
			else
			{
				r.name="丽丽";
				r.sex="女女女女";
			}
			x=(x+1)%2;
			
		}
	}
}

class Output implements Runnable
{
	private Res r;
	Output(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			System.out.println(r.name+"...."+r.sex);
		}
	}
}

public class Contact
{
	public static void main(String[] args)
	{
		Res r = new Res();
		Input in = new Input(r);
		Output out = new Output(r);
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		t1.start();
		t2.start();
		
	}

}

//代码结果错误示例:
mike....女女女女
mike....man
丽丽....女女女女
丽丽....man
.......

错误原因:在mike 和man 输入之后输入"丽丽"时,还未输入性别,结果已经被线程2输出。

解决方式:同步,加互斥锁 synchronized

package contact;

class Res
{
	String name;
	String sex;
}

class Input implements Runnable
{
	private Res r; 
	Input(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		int x=0;
		
		while(true)
		{
			synchronized (r) //加互斥锁
			{
				
			if(x==0)
		{
			r.name="mike";
			r.sex="man";
		}
			else
			{
				r.name="丽丽";
				r.sex="女女女女";
			}
			x=(x+1)%2;
		   }
		}
	}
}

class Output implements Runnable
{
	private Res r;
	Output(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			synchronized (r) //加互斥锁
			{
			System.out.println(r.name+"...."+r.sex);
		}
	    }
	}
}

public class Contact
{
	public static void main(String[] args)
	{
		Res r = new Res();
		Input in = new Input(r);
		Output out = new Output(r);
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		t1.start();
		t2.start();
		
	}

}

//加入互斥锁 synchronized后运行结果:
mike....man
mike....man
.......
丽丽....女女女女
丽丽....女女女女
.......
加了互斥锁 synchronized 不能解决问题,说明互斥锁出现错误
  • 检查错误:两个前提
  • 一是看是否有两个线程(或多个)需要加互斥锁的地方已经加上了互斥锁
  • 二是看所加的互斥锁是否一致(唯一)

互斥锁 synchronized(?)?处都可以填什么?
可以填 r、Input.class、Output.class、Contact.class

等待唤醒机制

为何输出多次?          
mike....man
mike....man
.......
丽丽....女女女女
丽丽....女女女女
  • 原因: 两个线程互相争夺cpu使用权,输入线程抢夺到后持续一段时间输入,等到某一时刻被输出线程抢到cpu,开始疯狂输出一段时间。
  • 那么,如何实现输入一个姓名性别,输出一个相应的姓名性别呢?
    这就需要使用我们的等待唤醒机制啦,这部分内容比较多而且更加重要,我们把它放到下一篇博客来讲解,嘻嘻嘻(才不是我想偷懒一天23333)
    敬请期待下一篇内容吧!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值