最近看了许多线程同步的内容,这里,简要记录我学习线程同步的过程。线程的概念就不说了,着重写遇到的各种问题。
首先要弄清楚的是,线程同步是什么情况,为什么会出现不同步。比如说我(被调用的对象)现在有100块钱,并告知了朋友A(线程1)和朋友B(线程2),朋友A问我借了50,于是我就只有50块钱了,而朋友B并不知道,准备把我的100块钱全部借走,但突然发现我只有50块钱,不够借了。这个过程就造成了线程不同步。
当多个线程调用同一个对象的时候,如果不采取措施,被调用对象的实际内容与线程中储存的该对象的内容很容易出现差异,即信息不同步。
下面的代码就是一个典型的例子
public class StringBufferTest { StringBuilder sb = new StringBuilder("12345"); public StringBuilder appendChar(char c,int id) { System.out.println(id+" -before,:"+sb); sb.append(c); System.out.println(id+" -later,:"+sb); return sb; } public static void main(String[] args){ StringBufferTest sbt = new StringBufferTest(); //开启5个线程 for(int i=0;i<5;i++){ new Thread(new addStringBuffer(sbt,i)).start(); } } } class addStringBuffer implements Runnable{ private StringBufferTest sbt; static char c=97; int id; public addStringBuffer(StringBufferTest sbt,int id){ this.sbt = sbt; this.id = id; } public void run(){ sbt.appendChar(c++,id); } }
代码的appendChar()实际上是重写了StringBuffer类中的append()方法,参数id纯粹是用来标记5个线程的id,从0-4。运行的结果如下:
从结果看出,id为0的线程,执行apend()方法前,StringBuilder的内容是12345,而执行apend()之后,却变成了12345cba。这说明,在id=0的线程执行之前,先完成了线程id=3和id=1的这两个线程。StringBuilder对象被前三个线程不分先后的调用,导致了其内容变得不可控制。典型的线程不同步的后果。(当然,结果页可能是同步的,这个很好理解)
解决这个问题,线程排队是一个不错的方法。对象A同一时间只能被一个线程调用,其他想调用对象A的线程要依次排队(就绪队列)。只有让当前线程结束之后,下一个线程才能调用对象A。这样就保证了对象A信息的同步。在JAVA中只需添加同步关键字,便可解决问题。
public synchronized StringBuilder appendChar(char c,int id) { System.out.println(" "+id+" -before,:"+sb); sb.append(c);// 往盘子里放鸡蛋 System.out.println(" "+id+" -later,:"+sb); return sb; }
运行的结果如下,
结果上可以看出,依次运行线程0-3-1-2-4,线程之间没有冲突,这样就保证的调用StringBuilder的同步。synchronized关键字锁住了它修饰的方法,保证了方法appendChar()同一时间只能在一个线程中运行,如果其他线程想调用appendChar()方法,就必须排队,等当前线程运行结束后,才能调用。
还有一个问题,为什么不是按线程id=0-1-2-3-4运行,这和synchronized有关系吗。synchronized关键字只是扮演了维护治安的作用,督促所有的线程(除了当前线程外)都排队,依次运行。至于谁先谁后,它不管。先到先运行。所以每次运行线程id的顺序可能不同,但保证了线程之间没有冲突。
相关推荐
Java 线程同步控制机制 线程同步是 Java 编程中的一种机制,用于控制多个线程之间的资源访问顺序,以避免线程之间的冲突和数据不一致。线程同步的目的就是避免线程“同步”执行,即让多个线程之间排队操作共享资源...
java线程同步java线程同步java线程同步
总结一下,Java线程同步的关键点: 1. **线程同步是为了解决共享资源的并发访问问题,防止数据不一致和冲突。** 2. **同步意味着线程排队,依次访问共享资源,而不是同时访问。** 3. **只有共享变量(可变状态)才...
在Java编程环境中,...总之,使用Java线程实现数据库主从同步更新是一种常见且实用的技术手段,它涉及到多线程编程、数据库操作、事务管理等多个方面。理解和掌握这些知识点对于开发高可用性的分布式系统至关重要。
"Java多线程同步.pdf" Java多线程同步是指在Java语言中,如何使用synchronized关键字和其他同步机制来确保多线程程序的正确执行。在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用...
Java线程同步与通信是多线程编程中的关键概念,用于解决并发访问共享资源时可能出现的数据不一致性和竞态条件问题。以下将详细介绍这两个主题,以及如何通过代码示例进行演示。 1. **线程同步**: 线程同步是确保...
java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料
在深入探讨Java线程同步调用这一主题之前,我们首先需要理解线程同步的基本概念及其在多线程环境中的重要性。线程同步是多线程编程中的一个关键概念,它确保了多个线程在访问共享资源时不会发生冲突,避免了数据不...
在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...
Java线程(二):线程同步synchronized和volatile 详细讲解Java 同步的原理技术资料
电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...
Java多线程同步是编程中一个非常重要的概念,特别是在并发编程中,用于解决多个线程访问共享资源时可能引发的数据不一致问题。本实例通过一个简单的火车票售票系统来演示同步机制的应用。 在这个实例中,我们创建了...
在Java编程中,线程同步和互斥是多线程编程中的重要概念,它们用于解决多个线程同时访问共享资源时可能出现的问题。本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费...
在Java中,线程同步是保证多线程安全...上述Java线程同步例子中涉及到的代码虽然是片段,但涵盖了线程同步处理的多个重要方面,帮助我们理解和使用Java线程同步机制,以及在设计和实现多线程应用程序时的实践和技巧。
本实例65着重讲解了Java线程同步的实现方法,帮助开发者理解和掌握如何在并发环境中保证代码的正确执行。 首先,我们要了解什么是线程。线程是程序中的执行流,每个线程都有自己的程序计数器、栈、局部变量和常量,...
总的来说,理解和掌握Java线程的创建、状态管理、同步机制和线程安全是进行多线程编程的基础,这对于开发高效、稳定的并发程序至关重要。在实际编程中,应充分利用Java提供的工具和机制,避免潜在的并发问题,提升...
Java中的`synchronized`关键字是用于实现线程同步的关键机制,主要目的是解决多线程环境下的数据安全问题。当多个线程访问共享资源时,如果没有适当的同步控制,可能会导致数据不一致或者竞态条件等问题。线程同步...
本文将深入探讨Java多线程中的关键知识点,包括创建线程、主线程、线程优先级、线程组、线程同步以及线程间的通信。 1. **创建线程** 在Java中,可以通过两种方式创建线程:继承`Thread`类或实现`Runnable`接口。...