java实现同步的两种方式

同步是多线程中的重要概念。同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果。同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字。

给一个方法增加synchronized修饰符之后就可以使它成为同步方法,这个方法可以是静态方法和非静态方法,但是不能是抽象类的抽象方法,也不能是接口中的接口方法。下面代码是一个同步方法的示例:

public synchronized void aMethod() {

// do something

}

public static synchronized void anotherMethod() {

// do something

}

线程在执行同步方法时是具有排它性的。当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出,从而导致它释放了该对象的同步锁之后。在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。

同步块是通过锁定一个指定的对象,来对同步块中包含的代码进行同步;而同步方法是对这个方法块里的代码进行同步,而这种情况下锁定的对象就是同步方法所属的主体对象自身。如果这个方法是静态同步方法呢?那么线程锁定的就不是这个类的对象了,也不是这个类自身,而是这个类对应的java.lang.Class类型的对象。同步方法和同步块之间的相互制约只限于同一个对象之间,所以静态同步方法只受它所属类的其它静态同步方法的制约,而跟这个类的实例(对象)没有关系。

如果一个对象既有同步方法,又有同步块,那么当其中任意一个同步方法或者同步块被某个线程执行时,这个对象就被锁定了,其他线程无法在此时访问这个对象的同步方法,也不能执行同步块。

synchronized 关键字用于保护共享数据。请大家注意“共享数据”,你一定要分清哪些数据是共享数据,请看下面的例子:

public class ThreadTest implements Runnable{

public synchronized void run(){

for(int i=0;i<10;i++) {

System.out.print(" " + i);

}

}

public static void main(String[] args) {

Runnable r1 = new ThreadTest(); //也可写成ThreadTest r1 = new ThreadTest();

Runnable r2 = new ThreadTest();

Thread t1 = new Thread(r1);

Thread t2 = new Thread(r2);

t1.start();

t2.start();

}}

在这个程序中,run()虽然被加上了synchronized 关键字,但保护的不是共享数据。因为这个程序中的t1,t2 是两个对象(r1,r2)的线程。而不同的对象的数据是不同的,r1,r2 有各自的run()方法,所以输出结果无法预知。

synchronized的目的是使同一个对象的多个线程,在某个时刻只有其中的一个线程可以访问这个对象的synchronized 数据。每个对象都有一个“锁标志”,当这个对象的一个线程访问这个对象的某个synchronized 数据时,这个对象的所有被synchronized 修饰的数据将被上锁(因为“锁标志”被当前线程拿走了),只有当前线程访问完它要访问的synchronized 数据时,当前线程才会释放“锁标志”,这样同一个对象的其它线程才有机会访问synchronized 数据。

时间: 2024-10-05 06:16:19

java实现同步的两种方式的相关文章

【转】SQL Server 2008 数据库同步的两种方式 (发布、订阅)

上篇中说了通过SQL JOB的方式对数据库的同步,这一节作为上一节的延续介绍通过发布订阅的方式实现数据库之间的同步操作.发布订阅份为两个步骤:1.发布.2.订阅.首先在数据源数据库服务器上对需要同步的数据进行发布,然后在目标数据库服务器上对上述发布进行订阅.发布可以发布一张表的部分数据,也可以对整张表进行发布.下面分别介绍发布.订阅的过程. 一.发布.发布需要用实际的服务器名称,不能使用服务器的IP地址进行.能发布的信息包括[表].[存储过程].[用户函数]如果使用IP会有错误,如下图: 具体发

Java开启线程的两种方式

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.ios培训..Net培训</a>.期待与您交流!------ Java开启线程的两种方式: 方式一:成为线程(Thread)的儿子,即继承Thread类简单代码如下:class Student extends Thread{Student(String name){super(name);}public

java.util.Arrays.sort两种方式的排序(及文件读写练习)

import java.io.*; import java.util.*; public class SortTest{ public static void main(String args[]) throws IOException, ClassNotFoundException { FileReader InWord = new FileReader(new File("words.txt")); BufferedReader in = new BufferedReader(In

SqlServer2008 数据库同步的两种方式(Sql JOB)

原文:SqlServer2008 数据库同步的两种方式(Sql JOB) 数据库同步是一种比较常用的功能.以下结合我自己的体会整理的,如果有理解不完全或者有误的地方望大牛不理赐教.下面介绍的就是数据库同步的两种方式: 1.SQL JOB的方式  sql Job的方式同步数据库就是通过SQL语句,将一个数据源中的数据同步到目标数据库中.特点是它可以灵活的通过SQL的方式进行数据库之间的同步操作.可以在制定的时间时间作为任务计划自动执行.缺点是需要写SQL来进行操作.既然是数据库之间的同步就涉及到数

(转)SqlServer2008 数据库同步的两种方式 (发布、订阅)

上篇中说了通过SQL JOB的方式对数据库的同步,这一节作为上一节的延续介绍通过发布订阅的方式实现数据库之间的同步操作.发布订阅份为两个步骤:1.发布.2订阅.首先在数据源数据库服务器上对需要同步的数据进行发布,然后在目标数据库服务器上对上述发布进行订阅.发布可以发布一张表的部分数据,也可以对整张表进行发布.下面分别介绍发布.订阅的过程. 1.发布.发布需要用实际的服务器名称,不能使用服务器的IP地址进行.能发布的信息包括[表].[存储过程].[用户函数]如果使用IP会有错误,如下图: 具体发布

SqlServer2008 数据库同步的两种方式 (发布、订阅)

尊重原著作:本文转载自http://www.cnblogs.com/tyb1222/archive/2011/05/31/2064944.html 上篇中说了通过SQL JOB的方式对数据库的同步,这一节作为上一节的延续介绍通过发布订阅的方式实现数据库之间的同步操作.发布订阅份为两个步骤:1.发布.2订阅.首先在数据源数据库服务器上对需要同步的数据进行发布,然后在目标数据库服务器上对上述发布进行订阅.发布可以发布一张表的部分数据,也可以对整张表进行发布.下面分别介绍发布.订阅的过程. 1.发布.

java 实现多线程的两种方式

一.问题引入 说到这两个方法就不得不说多线程,说到多线程就不得不提实现多线程的两种方式继承Thread类和实现Runable接口,下面先看这两种方式的区别. 二. Java中实现多线程的两种方式 1.  继承Thread类 /** * 使用Thread类模拟4个售票窗口共同卖100张火车票的程序,实际上是各卖100张 */ public class ThreadTest { public static void main(String[] args){ new MyThread().start(

SQL Server 2008 数据库同步的两种方式 (发布、订阅)

上篇中 说了通过SQL JOB的方式对数据库的同步,这一节作为上一节的延续介绍通过发布订阅的方式实现数据库之间的同步操作.发布订阅份为两个步骤:1.发布.2.订阅.首先 在数据源数据库服务器上对需要同步的数据进行发布,然后在目标数据库服务器上对上述发布进行订阅.发布可以发布一张表的部分数据,也可以对整张表进行发 布.下面分别介绍发布.订阅的过程. 一.发布.发布需要用实际的服务器名称,不能使用服务器的IP地址进行.能发布的信息包括[表].[存储过程].[用户函数]如果使用IP会有错误,如下图:

对Java代码加密的两种方式,防止反编译

使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的java.exe,并且可以实现项目源码绑定制定设备,防止部署到客户服务器的项目被整体拷贝. 两种加密方式 War 包加密 当你的项目在没有完成竣工的时候,不适合使用 war 文件,因为你的类会由于调试之类的经常改,这样来回删除.创建 war 文件很不爽,最好是你的项目已经完成了,不改了,那么就打个 w