由于多线程的访问出现延迟和线程的随机性,在使用多线程时往往会伴随安全性的问题,这些问题一旦出现将会是非常严重的。为了解决这种安全性问题,synchronized出现了。

synchronized用法一,放在方法内,必须传一个对象obj

synchronized(obj)
{
//需要被同步的代码
}

synchronized用法二,放在方法上,不需要传对象

public synchronized void method()
{
//该方法体中所有的代码都被同步了
}

例子:银行有个小金库,初始为0,有一天有两个富商来存金币,每人每次同时存100金币,没有使用同步的多线程代码

class Bank
{
private int gold=0;
public void add(int num)
{
try
{
Thread.sleep(10);
gold += num;
}
catch (Exception e)
{
System.out.println("银行内部错误,暂停服务!");
System.exit(0);
}
System.out.println("金库里有"+gold+"金币");
}
} class Business implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int i=0;i<3;i++)
{
b.add(100);
}
}
} class StoreGold
{
public static void main(String[] args)
{
Business b = new Business(); Thread t1 = new Thread(b,"张三");
Thread t2 = new Thread(b,"李四");
t1.start();
t2.start();
}
}

运行时,就有可能出现金库里有500金币两次等等错误情况,其原因是gold没有被同步,有被同时使用一个值的情况。在Bank的add方法中应该加上同步,如下

class Bank
{
private int gold=0;
public void add(int num)
{
synchronized(this)
{
try
{
Thread.sleep(10);
gold += num;
}
catch (Exception e)
{
System.out.println("银行内部错误,暂停服务!");
System.exit(0);
}
}
System.out.println("金库里有"+gold+"金币");
}
}

也可以把synchronized加在方法上,这样的写法边简单了,但是同步的内容就多了。同步函数的锁是this。

class Bank
{
private int gold=0;
public synchronized void add(int num)
{
try
{
Thread.sleep(10);
gold += num;
}
catch (Exception e)
{
System.out.println("银行内部错误,暂停服务!");
System.exit(0);
}
System.out.println("金库里有"+gold+"金币");
}
}

虽然同步可以让线程在处理某些事务时更为安全,但同时由于每个线程都多了拿锁、等待、释放锁等操作,所以会影响程序运行的速率。

那么什么代码需要被同步呢?

1,明确哪些代码是多线程运行代码

2,明确共享数据

3,明确多线程运行代码中哪些语句是操作共享数据的

同步使用的是什么锁呢?

1,函数使用的锁是this

2,静态函数使用的锁是类名.class,字节码文件对象

Java:多线程<二> 同步的更多相关文章

  1. Java多线程的同步控制记录

    Java多线程的同步控制记录 一.重入锁 重入锁完全可以代替 synchronized 关键字.在JDK 1.5 早期版本,重入锁的性能优于 synchronized.JDK 1.6 开始,对于 sy ...

  2. java 多线程二

    java 多线程一 java 多线程二 java 多线程三 java 多线程四 线程中断: /** * Created by root on 17-9-30. */ public class Test ...

  3. Java多线程之同步集合和并发集合

    Java多线程之同步集合和并发集合 不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有他们如何实现的线程安全. 同步集合类 Hashtable Vector 同 ...

  4. Java多线程编程(同步、死锁、生产消费者问题)

    Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...

  5. java多线程二之线程同步的三种方法

          java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...

  6. Java多线程的同步机制(synchronized)

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...

  7. Java多线程(二) —— 深入剖析ThreadLocal

    对Java多线程中的ThreadLocal类还不是很了解,所以在此总结一下. 主要参考了http://www.cnblogs.com/dolphin0520/p/3920407.html 中的文章. ...

  8. JAVA多线程线程同步问题

    线程同步 在多线程的编程环境下,可能看着没有问题的代码在运行几千上万或者更多次后,出现了一些看着很奇怪的问题,出现这样的问题的原因就是可能会有两个或者更多个线程进入了同一块业务处理代码中导致了判断失效 ...

  9. Java多线程synchronized同步

    非线程安全问题 “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程问题”.也即是说,方法中的变量永远是线程安全的. 如果多个线程共同访问1个对象中的实例变量,则可能线程 ...

  10. Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

随机推荐

  1. linux 查看磁盘剩余命令

    df -hl命令查看各磁盘的大小,使用情况,挂载点等信息. du -bs dir_name查看具体目录的空间大小

  2. 从出租车司机到大BOSS的转型之路

    来深圳之前,曾有人这样告诉我:在深圳千万不能以貌取人,打扮不起眼,也许他转身开的座驾就是宝马.奔驰;不管一个人多么邋遢俗气,也别瞧不起人家,也许他的手提袋里就是成捆的人民币现金;不管一个人打扮的多么土 ...

  3. struts 数据验证

    1. validate()验证 将对页面表单验证的内容写到validate()方法中,实现验证和业务处理内容的分离 在Action中添加 validate()方法   public void vali ...

  4. An internal error occurred during: "Building workspace".

    当在eclipse中的web工程中增加了extjs4,出现An internal error occurred during: "Building workspace". Java ...

  5. SQL2005中的事务与锁定(九)- 转载

    ------------------------------------------------------------------------ -- Author : HappyFlyStone - ...

  6. 整理课堂笔记 pl/sql orcale异常

      1>>>>>异常错误处理 1 >预定义的异常处理 预定义说明的部分 ORACLE 异常错误对这种异常情况的处理,只需在PL/SQL块的异常处理部分,直接引用相应 ...

  7. Locality Sensitive Hash 局部敏感哈希

    Locality Sensitive Hash是一种常见的用于处理高维向量的索引办法.与其它基于Tree的数据结构,诸如KD-Tree.SR-Tree相比,它较好地克服了Curse of Dimens ...

  8. hdu 5779 Tower Defence

    题意:考虑由$n$个结点构成的无向图,每条边的长度均为$1$,问有多少种构图方法使得结点$1$与任意其它节点之间的最短距离均不等于$k$(无法到达时距离等于无穷大),输出答案对$1e9+7$取模.$1 ...

  9. WPFのInkCanvas作为蒙版透明笔迹不透明

    本人最近利用inkcavas做一个蒙版的功能,结果发现笔迹稀释了,经过一番查找发现:应该讲inkcavas的背景设置为白色,然后透明,而不是将整个控件透明,具体代码: <InkCanvas Na ...

  10. RCP:如何保存TaskList及如何获取TaskList

    如果我们在Eclipse RCP程序中添加TaskList View,用来管理Task或者TODO项,如下代码: PlatformUI.getWorkbench().getActiveWorkbenc ...