synchronized使用之基本原则:

synchronized可以锁方法,也可以锁代码片段,但要实现互斥的基本就是在想要互斥的代码上加”同一把锁“,也就是同一个对象,也就是用==判断等于true的对象

下面看一个例子:

Work.java    真正做事情的类

 package com.yzl;

 public class Work {
/**
* 未同步的
* @param name
*/
public void noSynwrite(String name){
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
} /**
* 使用同步块,并使用Work的实例对象做为锁
* 此方法的同步需保证是调用该方法的work对象是同一个
* @param name
*/
public void write1(String name){
synchronized (this) {
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
}
} /**
* 使用同步块,并使用Work的字节码做为锁
* @param name
*/
public void write1WithStatic(String name){
synchronized (Work.class) {
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
}
} /**
* 使用同步的方法,锁对象为ork的实例对象
* 此方法的同步需保证是调用该方法的work对象是同一个
* @param name
*/
public synchronized void write2(String name){
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
} /**
* 静态方法的同步方法,同步的对象是对象的字节码,也就是Work.class
* 如果要与上面的方法一起使用并保持互斥,则可以把write1的锁对象this改成Work.class
* @param name
*/
public synchronized static void write3(String name){
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
}
}

测试类ThreadPart_2.java

 package com.yzl;

 /**
* 传统的线程互斥
* 原理:使用同一个对象(锁)才能实现,
* 静态方法的同步则只能使用类的字节码也就是ClassName.class来做锁
* @author yzl
*
*/
public class ThreadPart_2 {
public static void main(String[] args) {
noSyn();
synWithOneObj();
synWithOneStaticObj();
} /**
* 未线程同步的
*/
private static void noSyn(){
final Work work = new Work(); Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.noSynwrite("wangwu");
}
}
});
thread.start(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.noSynwrite("zhangsan");
}
}
});
thread1.start();
} /**
* 使用同一个实例对象做为锁的
*/
private static void synWithOneObj(){
final Work work = new Work(); Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.write1("wangwu");
}
}
});
thread.start(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.write2("zhangsan");
}
}
});
thread1.start();
} /**
* 使用同一个类的字节码做为锁的
*/
private static void synWithOneStaticObj(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
new Work().noSynwrite("wangwu");
}
}
});
thread.start(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
Work.write3("zhangsan");
}
}
});
thread1.start();
}
}

将上面ThreadPart_2的第12、13、14行代码分别依次执行,

第12行代码将出现如下类似结果:

//运行结果部分示例
zhangsan
zhwu
wangwu
wangangsan
zhangsawangwu

第13和14行将是正常的打印各自的名字

2、传统的线程互斥synchronized的更多相关文章

  1. 传统的线程互斥技术:Synchronized关键字

    多个线程操作同一个方法或变量时常常出现错误,要保证每个线程都正常运行就要通过加锁,每次只有一个能够拿到锁通过.如下: package cn.sp.thread; /** * Created by 2Y ...

  2. 线程互斥synchronized

    /** * * 线程互斥,采用synchronized关键字可以实现线程与线程之间的互斥,要注意的是在synchronized上的对象要是同一个,才可以 * 保证在同一时刻,只有一个线程可以执行syn ...

  3. 【Java并发专题之三】Java线程互斥、协作原理

    (I)Java线程互斥原理之synchronized原理 从JDK5引入CAS原子操作,但没有对synchronized关键字做优化,而是增加了J.U.C.concurrent,concurrent包 ...

  4. 【原】iOS多线程之线程间通信和线程互斥

    线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...

  5. java线程安全— synchronized和volatile

    java线程安全— synchronized和volatile package threadsafe; public class TranditionalThreadSynchronized { pu ...

  6. java多线程与线程并发二:线程互斥

    本文章内容整理自:张孝祥_Java多线程与并发库高级应用视频教程 当两条线程访问同一个资源时,可能会出现安全隐患.以打印字符串为例,先看下面的代码: // public class Test2 { p ...

  7. Java线程同步synchronized的理解

    JVM中(留神:马上讲到的这两个存储区只在JVM内部与物理存储区无关)存在一个主内存(Main Memory),Java中所有的变量存储在主内存中,所有实例和实例的字段都在此区域,对于所有的线程是共享 ...

  8. GIL与线程互斥锁

    GIL 是解释器级别的锁,是限制只有一个原生线程运行,防止多个原生线程之间修改底层的共享数据.而线程互斥锁是防止多个线程同时修改python内存空间的共享数据.

  9. C#中的多线程与线程互斥

    通过多线程,C#可以并行地执行代码. 每一个线程都有它独立的执行路径,所有线程都能访问共有变量. 这就引发了线程竞争 这时就需要使用线程安全的处理方式使得线程互斥 先来看一段多线程代码 using S ...

随机推荐

  1. C#零基础入门04:打老鼠初级之枚举、重构、事件处理器

    一:为界面加入"开始"."暂停"."停止" 经过上节课程我们的交互的过程,我们的程序增加了用户友好度,同时也可以记录更为详尽的成绩了.但是我 ...

  2. C# 根据注册表获取当前用户的常用目录整理

    1.使用C#获取当前程序或解决方案的路径 2.使用C#获取当前登录用户的相关目录 3.也可以获取当前系统通用目录 4.获取Windows系统的目录,从注册表中获取. 一.当前用户的目录,HKEY_Cu ...

  3. 访问修饰符(C# 编程指南)

    所有类型和类型成员都具有可访问性级别,该级别可以控制是否可以从你的程序集或其他程序集中的其他代码中使用它们. 可以使用以下访问修饰符在进行声明时指定类型或成员的可访问性: public同一程序集中的任 ...

  4. 优化算法动画演示Alec Radford's animations for optimization algorithms

    Alec Radford has created some great animations comparing optimization algorithms SGD, Momentum, NAG, ...

  5. 细思极恐-你真的会写java吗?

    导语 自2013年毕业后,今年已经是我工作的第4个年头了,总在做java相关的工作,终于有时间坐下来,写一篇关于java写法的一篇文章,来探讨一下如果你真的是一个java程序员,那你真的会写java吗 ...

  6. 整理:产品文档规范——BRD、PRD和MRD

    BRD和MRD,PRD一起被认为是从市场到产品需要建立的文档规范. BRD 商业需求文档--BRD(Business Requirements Document) 商业需求文档重点放在定义产品的商业需 ...

  7. Domino(群组工作软件)

    ylbtech-Miscellaneos: Domino(群组工作软件) “Domino”是一种群组工作软件.使用了Domino的服务器就叫Domino服务器Domino的功能强大,界面丰富,主要用于 ...

  8. json schema校验

    工作中使用到了json schema格式校验的问题,在网上查了些资料,结合自己的理解记录一下. json schema可以对json结果字符串做出一些约束,例如: 1. 值类型是:array, obj ...

  9. go语言之进阶篇error接口的使用

    1.error接口的使用 示例: package main import "fmt" import "errors" func main() { //var e ...

  10. cesium and three.js【转】

    https://blog.csdn.net/zhishiqu/article/details/79077883 这是威尔逊Muktar关于整合Three.js与铯的客人帖子.Three.js是一个轻量 ...