多线程学习笔记(2)

多线程很重要的一部分是锁的问题,保证数据的同步,特别是在银行这些对数据特别敏感的行业,对于一个不会多线程的程序员,作为银行行业的招聘官基本是绝对不会把他招入麾下的,隐患太大,下面我来说一下一般我们是怎么来使代码同步的。我先贴几组代码,最后在对比总结。
public class SyThreadTest {
	
	public static void main(String[] args) {
		new Thread(new Runnable() {
			public void run() {
				while(true){
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					sythread.sys1("1234567");
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			public void run() {
				while(true){
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					sythread.sys1("abcdefg");
				}
			}
		}).start();
	}
	static class sythread{
		public synchronized static void sys1(String name){
			for (int i = 0; i < name.length(); i++) {
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
	}
	

首先Synchronized这个关键词,是同步的核心,他相当于之后版本的lock.其意思也是锁的意思,这段代码输出的结果不会乱,都是输出“1234567”和”abcdefg“,不会产生"123abc"这类互相参杂的数据。

	static class sythread{
		public synchronized static void sys1(String name){
			for (int i = 0; i < name.length(); i++) {
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
	}

这里我去掉了Synchronized这个关键词,他相当于没加锁,这时候的运行效果如下图


我来具体说一下此图意思,我们假定A为10,线程1,2同时运行(不考虑处理速度),当线程1运行,获得资源A的值为10,这时候A+1为11,假如这时候线程2还没拿到资源A,那么,等A执行完了在拿到资源A,这样没有问题,线程2会拿到正确的资源A=11,然后11-1=10,这时候情况假如是这样的,这时候11-1没有执行完,还没有给这个资源A,那么线程1下次拿到的资源A还是A=11,然后11+1=12,这时候大家就发现了,和我们想象中需要的不一样。

这时候我们来说说Synchronized在这里的作用是什么,他相当于保证了代码块或者方法的同步,上面已经贴过怎么同步方法,下面代码为同步代码块

	public static void sys1(String name){
			synchronized(共同对象){
				for (int i = 0; i < name.length(); i++) {
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}
		}

这也能达到同样的同步效果,这里要说一下,不要在方法上修饰synchronized又同时在代码块上用此关键词,容易造成死锁,使得程序不继续往下运行,这个应该要避免。

  • 对于实例的同步方法,使用this即当前实例对象
  • 对于静态的同步方法,使用当前类的字节码对象。

这里还有一个共同对象我要来说一下,这个共同对象见名知意,意思就是这个参数必须是共同的对象,相当于现实中的同一把钥匙,你用钥匙开了门,我就要等你开好门出来,把钥匙给我,我在用这个钥匙去开这个门,假如不是共同的对象应该也好理解,我开我的门,你开你的门,这样就达不到我们要的效果。

也就是说使用同步方法的话,同步锁只能是this或者当前类的字节码对象。所以根据同步锁必须互斥的前提,如果同时使用synchronized代码块和synchronized方法对同一个共享资源进行线程同步,synchronized代码块的同步锁也必须跟synchronized方法一样(要么是this,要么是类的字节码对象通俗说就是class)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值