精华内容
下载资源
问答
  • 线程的同步 如果线程不同步,会发生两个线程抢占资源的问题;例如火车票出售时,只有最后一张票,但两个人一起买就会出现系统问题。所以为了避免资源抢占的问题,在使用线程的同步时应该考虑线程的安全 1.不安全的...

    线程的同步

    如果线程不同步,会发生两个线程抢占资源的问题;例如火车票出售时,只有最后一张票,但两个人一起买就会出现系统问题。所以为了避免资源抢占的问题,在使用线程的同步时应该考虑线程的安全

    1.不安全的线程:
    同一进程下不同的线程是共享系统资源的,资源好比一个独木桥,如果两个线程,同时过独木桥的话就会发生不安全的情况(资源的抢用会造成:脏数据,死锁等问题)

    2.安全的线程
    过独木桥时,一个先给出指令先过桥,过完后再次发出指令,已经完成过桥
    要保证线程的安全:需要给线程加锁:
    加锁—’过桥‘—解锁

    加锁:synchronized关键字
    同步方法:synchronized void method(){
    }
    同步代码块 synchronized(Object){

    } Object:任意对象,仅作为加锁的标志

    首先举一个不安全的线程同步例子:

    //模拟售票系统
    public class 同步 implements Runnable{
        int num = 10;//票池的总数
    	public static void main(String[] args) {
    		同步 d =new 同步();
    		Thread t1= new Thread(d,"线程1");//售票机1
    		Thread t2= new Thread(d,"线程2");//售票机2
    		Thread t3= new Thread(d,"线程3");//售票机3
    		Thread t4= new Thread(d,"线程4");//售票机4
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    	public void run() {
    		while(true) {
    			if(num>0) 
    				try {
    					Thread.sleep(100);//休眠100毫秒
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println("票数:"+num);
    				num--;
    				if(num<0) {
    					break;
    				}
    			}
    		}
    		
    	}
    

    结果如下:
    票数:10
    票数:7
    票数:8
    票数:9
    票数:6
    票数:3
    票数:4
    票数:5
    票数:2
    票数:1
    票数:0
    票数:-1
    票数:-2
    票数:-3

    采用同步代码块的方法使线程安全:

    //模拟售票系统
    public class 同步 implements Runnable{
        int num = 10;//票池的总数
    	public static void main(String[] args) {
    		同步 d =new 同步();
    		Thread t1= new Thread(d,"线程1");//售票机1
    		Thread t2= new Thread(d,"线程2");//售票机2
    		Thread t3= new Thread(d,"线程3");//售票机3
    		Thread t4= new Thread(d,"线程4");//售票机4
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    	public void run() {
    		while(true) {
    			synchronized (this) {//同步代码块,所以线程同步此代码块
    				if(num>0) {
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						// TODO 自动生成的 catch 块
    						e.printStackTrace();
    					}
    					System.out.println("票数:"+num);
    					num--;
    					if(num<0) {
    						System.out.println("已售空");
    						break;
    					}
    				}
    			}
    		}
    	}
    		
    }
    

    采用同步方法的解决方法

    //模拟售票系统
    public class 同步 implements Runnable{
        int num = 10;//票池的总数
    	public static void main(String[] args) {
    		同步 d =new 同步();
    		Thread t1= new Thread(d,"线程1");//售票机1
    		Thread t2= new Thread(d,"线程2");//售票机2
    		Thread t3= new Thread(d,"线程3");//售票机3
    		Thread t4= new Thread(d,"线程4");//售票机4
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    	private synchronized void sell() {//线程同步的方法
    		if(num>0) {
    			try {
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				// TODO 自动生成的 catch 块
    				e.printStackTrace();
    			}
    			System.out.println("票数:"+num);
    			num--;
    			if(num<0) {
    				System.out.println("已售空");
    			}
    		}
    	}
    	public void run() {
    		while(true) {
    			sell();
    			}
    	}
    		
    }
    
    展开全文
  • Java线程的同步和通讯

    2016-05-03 17:01:38
    像你所看到Java为此提供了独特,语言水平上支持。同步的关键是管程(也叫信号量semaphore)概念。管程是一个互斥独占锁定对象,或称互斥体(mutex)。在给定时间,仅有一个线程可以获得管程。当一个...

               当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用。达到此目的的过程叫做同步(synchronization)。像你所看到的,Java为此提供了独特的,语言水平上的支持。同步的关键是管程(也叫信号量semaphore)的概念。管程是一个互斥独占锁定的对象,或称互斥体(mutex)。在给定的时间,仅有一个线程可以获得管程。当一个线程需要锁定,它必须进入管程。所有其他的试图进入已经锁定的管程的线程必须挂起直到第一个线程退出管程。这些其他的线程被称为等待管程。一个拥有管程的线程如果愿意的话可以再次进入相同的管程。在java程序中实现同步必须对共享的资源使用synchronized关键字,如:

    class Demo{

          synchronized void test(){

    //方法体}

    }

    或者是在调用该资源的时候使用关键字:

    class Test implements Runnable {

    Demo demo;

    public void run(){

    synchronized(demo){

    demo.test();}

    }

    }

         当然实现同步的关键必须让共享的资源同时让需要同步的单位同时享有机会。

            说道线程,不由得就会想到进程,毕竟在尚未接触这门语言的时候我们启动任务管理器的时候,特别是在程序卡死重启的过程中,系统提示程序还是运行,就需要打开第二栏的进程管理,从而结束进程,扯远了,在学到线程的时候,或许对理解进程乃至程序、计算机传输数据可能都会有一些模糊的概念了,对比二者确实有很多相似之处,二者的关系如同主水管接了很多分支,然后分支又分支,再分支的或许就是线程了,而进程就是分支,通过这个对比便能很好的理解线程和进程了,首先是线程肯定是要被进程所包含的,Java也能够被看成是一个进程,而线程是可以共享资源的进程是不能够的,进程是一个独立的运行环境,线程可以看做是轻量级的进程。

            说到通讯问题,这事情瞬间就高大上了,到底是发微信,还是微博私信呢?看来都不是,就是在它耳边轻轻的说就行了,老师举得例子是生产和消费的通讯问题,生产和消费的中间放着的便是产品了,所以通讯的前提还是得同步,也就是当下比较流行的信息对称的意味,然后就得通过一些方式来判断了,比如生产者先生产一个商品,然后在通知消费者前来消费,这里就很考究了, 调用的是notify()方法,前来通讯的,当然也可以判断,当生产者没有商品的时候,救通知消费者等一等使用wait()方法,在这里补充一下(wait(),notify(),notifyAll()不属于Thread类,而是属于Object基本类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.)对于消费者是一样的,就这样完成了通讯的过程,具体例子在上一篇。

    展开全文
  • Java线程的同步和异步的区别

    千次阅读 2014-05-20 18:08:12
    1.    多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程...系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制

    1.

                                                                    同步与异步

       多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线

    程的处理的数据,而B线程又修改了A线程处理的数理。显然这是由于全局资源造成的,有时为了解

    决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲

    系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制


    同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求

          不到,怎么办,A线程只能等待下去

    异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程

          仍然请求的到,A线程无需等待


    显然,同步最最安全,最保险的。而异步不安全,容易导致死锁,这样一个线程死掉就会导致整个

    进程崩溃,但没有同步机制的存在,性能会有所提升


    java中实现多线程

    1)继承Thread,重写里面的run方法

    2)实现runnable接口

     

    举个例子:普通B/S模式(同步)AJAX技术(异步)

    同步:提交请求->等待服务器处理->处理完返回这个期间客户端浏览器不能干任何事

    异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

    可见,彼“同步”非此“同步”——我们说的java中的那个共享数据同步(synchronized)

    一个同步的对象是指行为(动作),一个是同步的对象是指物质(共享数据)。


    一、关键字:

    thread(线程)、thread-safe(线程安全)、intercurrent(并发的)

    synchronized(同步的)、asynchronized(异步的)、

    volatile(易变的)、atomic(原子的)、share(共享)

    二、概念

    1.

    要跨线程维护正确的可见性,只要在几个线程之间分享非 final 变量,就必须使用 synchronized(或 volatile)

    以确保一个线程可以看见另一个线程做的更改。

    2、

    为了在线程之间进行可靠的通信,也为了互斥访问,同步是必须的。这归因于java语言规范的内存模型,它规定了:

    一个线程所做的变化何时以及如何变成对其它线程可见。

    3.

    多线程将异步行为引进程序,所以在需要同步时,必须有一种方法强制进行。例如:如果2个线程想要通信并且要

    共享一个复杂的数据结构,如链表,此时需要确保它们互不冲突,也就是必须阻止B线程在A线程读数据的过程中

    向链表里面写数据(A获得了锁,B必须等A释放了该锁)

    4.同步

    java在一个旧的的进程同步模型——监控器(Monitor)的基础上实现了一个巧妙的方案:监控器是一个控制机制,

    可以认为是一个很小的、只能容纳一个线程的盒子,一旦一个线程进入监控器,其它的线程必须等待,直到那个

    线程退出监控为止。通过这种方式,一个监控器可以保证共享资源在同一时刻只可被一个线程使用。这种方式称

    之为同步。(一旦一个线程进入一个实例的任何同步方法,别的线程将不能进入该同一实例的其它同步方法,

    但是该实例的非同步方法仍然能够被调用)。

    5.同步和多线程关系:没多线程环境就不需要同步;有多线程环境也不一定需要同步。


    6.锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)

     

    互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议

    ,这样,一次就只有一个线程能够使用该共享数据。


    可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个

    线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前

    的值或不一致的值,这将引发许多严重问题


    小结:为了防止多个线程并发对同一数据的修改,所以需要同步,否则会造成数据不一致(就是所

    谓的:线程安全。如java集合框架中Hashtable和Vector是线程安全的。我们的大部分程序都不是线

    程安全的,因为没有进行同步,而且我们没有必要,因为大部分情况根本没有多线程环境)


    7. 不要搞混了:同步、异步


    举个例子:普通B/S模式(同步)AJAX技术(异步)同步:提交请求->等待服务器处理->处理完返回 这个期间客户端浏览器不能干任何事

    异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕可见,彼“同步”非此“同步”

    ——我们说的java中的那个共享数据同步(synchronized)

    一个同步的对象是指行为(动作),一个是同步的对象是指物质(共享数据)。

    8、

     Java同步机制有4种实现方式:(部分引用网上资源)

    ①    ThreadLocal ② synchronized( ) ③ wait() 与 notify() ④ volatile

    目的:都是为了解决多线程中的对同一变量的访问冲突


    ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该变量的

    线程提供一     个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程

    副本冲突。

    优势:提供了线程安全的共享对象

    与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之

    间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源

    这样当然不需要多个线程进行同步了。

       volatile
        volatile 修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且

    当成员变量发生变化时,强迫线程将变化值回写到共享内存。

    优势:这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。缘由:Java 语言规范

    中指出,为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开

    同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某个对象交互时,就必须要

    注意到要让线程及时的得到共享成员变量的变化。而 volatile 关键字就是提示 VM :对于这个成

    员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。

    使用技巧:在两个或者更多的线程访问的成员变量上使用 volatile 。当要访问的变量已在

    synchronized 代码块中,或者为常量时,不必使用。


            线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的

    是B。只在某些动作时才进行A和B的同步,因此存在A和B不一致的情况。volatile就是用来避免这种

    情况的。 volatile告诉jvm,它所修饰的变量不保留拷贝,直接访问主内存中的(读操作多时使用

    较好;线程间需要通信,本条做不到)

    Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自

    动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的

    一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。


    您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理

    想的线程安全,必须同时满足下面两个条件:

    对变量的写操作不依赖于当前值;该变量没有包含在具有其他变量的不变式中。

     

      sleep() vs wait()
        sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监

    控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
        wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁

    定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁

    进入运行状态。

    (如果变量被声明为volatile,在每次访问时都会和主存一致;如果变量在同步方法或者同步块中

    被访问,当在方法或者块的入口处获得锁以及方法或者块退出时释放锁时变量被同步。)


    三、例子:

    Demo1:

    package test.thread;

    class SynTest{


    //非同步

    static void method(Thread thread){

    System.out.println("begin "+thread.getName());

    try{

    Thread.sleep(2000);

    }catch(Exception ex){

    ex.printStackTrace();

    }

    System.out.println("end "+thread.getName());

    }

     

    //同步方式一:同步方法

    synchronized static void method1(Thread thread){//这个方法是同步的方法,每次只有一

    个线程可以进来

    System.out.println("begin "+thread.getName());

    try{

    Thread.sleep(2000);

    }catch(Exception ex){

    ex.printStackTrace();

    }

    System.out.println("end "+thread.getName());

    }

     

    //同步方式二:同步代码块

    static void method2(Thread thread){

    synchronized(SynTest.class) {

    System.out.println("begin "+thread.getName());

    try{

    Thread.sleep(2000);

    }catch(Exception ex){

    ex.printStackTrace();

    }

    System.out.println("end "+thread.getName());

    }

    }

     

     

    //同步方式三:使用同步对象锁

    private static Object _lock1=new Object();

    private static byte _lock2[]={};//据说,此锁更可提高性能。源于:锁的对象越小越好

    static void method3(Thread thread){

    synchronized(_lock1) {

    System.out.println("begin "+thread.getName());

    try{

    Thread.sleep(2000);

    }catch(Exception ex){

    ex.printStackTrace();

    }

    System.out.println("end "+thread.getName());

    }

    }

     

    public static void main(String[] args){

    //启动3个线程,这里用了匿名类

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

    new Thread(){

    public void run(){

    method(this);

    //method1(this);

    //method2(this);

    //method3(this);

    }

    }.start();

    }

    }

    }

     

     

     

     

     

     

    Demo2:

    package test.thread;

     

    import com.util.LogUtil;

     

     

    public class SynTest2 {

     

    public static void main(String[] args){

    Callme target=new Callme();

    Caller ob1=new Caller(target,"Hello");

    Caller ob2=new Caller(target,"Synchronized");

    Caller ob3=new Caller(target,"World");

    }

    }

     

    class Callme{

     

     

    synchronized void test(){

    LogUtil.log("测试是否是:一旦一个线程进入一个实例的任何同步方法,别的线程将不能

    进入该同一实例的其它同步方法,但是该实例的非同步方法仍然能够被调用");

    }

     

    void nonsynCall(String msg){

    LogUtil.log("["+msg);

    LogUtil.log("]");

    }

     

    synchronized void synCall(String msg){

    LogUtil.logPrint("["+msg);

    LogUtil.log("]");

    }

    }

     

    class Caller implements Runnable{

    String msg;

    Callme target;

    Thread t;

     

    Caller(Callme target,String msg){

    this.target=target;

    this.msg=msg;

    t=new Thread(this);

    t.start();

    }

     

    public void run() {

    // TODO Auto-generated method stub

    //target.nonsynCall(msg);

    target.synCall(msg);

    target.test();

    }

     

    }



    参考自:http://blog.sina.com.cn/s/blog_6af29f290100s7qj.html



    展开全文
  • Java线程的同步笔记

    千次阅读 2009-03-30 19:48:00
    但有时会看到一些关于线程的错误用法。下面列出一些应该注意的问题。 1.同步对象的恒定性 All java objects are references. 对于局部变量和参数来说,java里面的int, float, double, boolean等基本数据类型,都在...


    Java的线程编程非常简单。但有时会看到一些关于线程的错误用法。下面列出一些应该注意的问题。
    1.同步对象的恒定性
    All java objects are references.

    对于局部变量和参数来说,java里面的int, float, double, boolean等基本数据类型,都在栈上。这些基本类型是无法同步的;java里面的对象(根对象是Object),全都在堆里,指向对象的reference在栈上。

    java中的同步对象,实际上是对于reference所指的“对象地址”进行同步。
    需要注意的问题是,千万不要对同步对象重新赋值。举个例子。
    class A implements Runnable{
      Object lock = new Object();

    void run(){
      for(...){
        synchronized(lock){
          // do something
          ...
          lock = new Object();
        }
      }
    }

    run函数里面的这段同步代码实际上是毫无意义的。因为每一次lock都给重新分配了新的对象的reference,每个线程都在新的reference同步。
    大家可能觉得奇怪,怎么会举这么一个例子。因为我见过这样的代码,同步对象在其它的函数里被重新赋了新值。
    这种问题很难查出来。
    所以,一般应该把同步对象声明为final.
    final Object lock = new Object();



    使用Singleton Pattern 设计模式来获取同步对象,也是一种很好的选择。

    2.如何放置共享数据
    实现线程,有两种方法,一种是继承Thread类,一种是实现Runnable接口。

    上面举的例子,采用实现Runnable接口的方法。本文推荐这种方法。

    首先,把需要共享的数据放在一个实现Runnable接口的类里面,然后,把这个类的实例传给多个Thread的构造方法。这样,新创建的多个Thread,都共同拥有一个Runnable实例,共享同一份数据。

    如果采用继承Thread类的方法,就只好使用static静态成员了。如果共享的数据比较多,就需要大量的static静态成员,令程序数据结构混乱,难以扩展。这种情况应该尽量避免。

    编写一段多线程代码,处理一个稍微复杂点的问题。两种方法的优劣,一试便知。

    3.同步的粒度
    线程同步的粒度越小越好,即,线程同步的代码块越小越好。尽量避免用synchronized修饰符来声明方法。尽量使用synchronized(anObject)的方式,如果不想引入新的同步对象,使用synchronized(this)的方式。而且,synchronized代码块越小越好。

    4.线程之间的通知
    这里使用“通知”这个词,而不用“通信”这个词,是为了避免词义的扩大化。

    线程之间的通知,通过Object对象的wait()和notify() 或notifyAll() 方法实现。

    下面用一个例子,来说明其工作原理:

    假设有两个线程,A和B。共同拥有一个同步对象,lock。

    1.首先,线程A通过synchronized(lock) 获得lock同步对象,然后调用lock.wait()函数,放弃lock同步对象,线程A停止运行,进入等待队列。

    2.线程B通过synchronized(lock) 获得线程A放弃的lock同步对象,做完一定的处理,然后调用 lock.notify() 或者lock.notifyAll() 通知等待队列里面的线程A。

    3.线程A从等待队列里面出来,进入ready队列,等待调度。

    4.线程B继续处理,出了synchronized(lock)块之后,放弃lock同步对象。

    5.线程A获得lock同步对象,继续运行。

    class SharedResource implements Runnable {
    Object lock = new Object();

    public void run() {
    // 获得当前线程的名称
    String threadName = Thread.currentThread().getName();
    if ("A".equals(threadName)) {
    synchronized (lock) { //线程通过synchronized(lock)获得lock同步对象
    try {
    System.out.println("A gives up lock.");
    lock.wait(); //调用lock.wait()函数,放弃lock同步对象.
    // 线程停止运行,进入等待队列中
    } catch (InterruptedException e) {
    }
    // 线程A重新获得lock同步对象之后,继续运行
    System.out.println("A got lock again and continue to run.");
    } // end of synchronized(lock)
    }
    if ("B".equals(threadName)) {
    synchronized (lock) {// 线程通过synchronized(lock)获得线程A放弃的lock同步对象
    System.out.println("B got the lock");
    lock.notify(); // 通知等待队列里的线程A,进入ready队列,等待调度.
    // 线程B继续执行出了synchronized块后放弃对lock同步对象.
    System.out.println("B gives up lock.");
    } // end of synchronized(lock)
    boolean hasLock = Thread.holdsLock(lock); // 检查B是否拥有lock同步对象.
    System.out.println("B has lock ? -- " + hasLock); // false.
    }
    }
    }

    public class TestMain {
    public static void main(String[]args) {
    Runnable resource = new SharedResource();
    Thread A = new Thread(resource, "A");
    A.start();
    // 强迫主线程停止运行,以便线程A开始运行.
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    }
    Thread B = new Thread(resource, "B");
    B.start();
    }
    }
    //console
    A gives up lock.
    B got the lock
    B gives up lock.
    B has lock ? -- false
    A got lock again and continue to run.



    5.跨类的同步对象
    对于简单的问题,可以把访问共享资源的同步代码都放在一个类里面。

    但是对于复杂的问题,我们需要把问题分为几个部分来处理,需要几个不同的类来处理问题。这时,就需要在不同的类中,共享同步对象。比如,在生产者和消费者之间共享同步对象,在读者和写者之间共享同步对象。

    如何在不同的类中,共享同步对象。有几种方法实现,

    (1)前面讲过的方法,使用static静态成员,(或者使用Singleton Pattern.)

    (2)用参数传递的方法,把同步对象传递给不同的类。

    (3)利用字符串常量的“原子性”。



    对于第三种方法,这里做一下解释。一般来说,程序代码中的字符串常量经过编译之后,都具有唯一性,即,内存中不会存在两份相同的字符串常量。

    (通常情况下,C++,C语言程序编译之后,也具有同样的特性。)

    比如,我们有如下代码。

    String A = “atom”;

    String B = “atom”;

    我们有理由认为,A和B指向同一个字符串常量。即,A==B。

    注意,声明字符串变量的代码,不符合上面的规则。

    String C= new String(“atom”);

    String D = new String(“atom”);

    这里的C和D的声明是字符串变量的声明,所以,C != D。



    有了上述的认识,我们就可以使用字符串常量作为同步对象。

    比如我们在不同的类中,使用synchronized(“myLock”), “myLock”.wait(),“myLock”.notify(), 这样的代码,就能够实现不同类之间的线程同步。

    本文并不强烈推荐这种用法,只是说明,有这样一种方法存在。



    本文推荐第二种方法,(2)用参数传递的方法,把同步对象传递给不同的类。

    展开全文
  • Java线程的同步与锁-java同步和锁定

    千次阅读 2011-09-07 22:34:41
    线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。 例如:两个线程ThreadA、ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据。   public class Foo {  private int x = 100; ...
  • 程序、进程和线程   程序是计算机指令集合,它以文件形式存储在磁盘上。 进程:是一个程序在其自身地址空间中一次执行活动。 进程是资源申请、调度和独立运行单位,因此,它使用系统中运行...
  • Java线程同步

    千次阅读 2018-01-06 17:56:53
    上一篇主要介绍了在Java中使用多线程,这一篇将总结Java线程的同步 线程同步 最典型的例子就是银行取钱例子,两个线程同时取钱的时候会出现余额小于0的情况,即并发线程“同时”修改了共享对象的成员变量,为了...
  • java线程的同步概念

    2019-04-10 11:00:08
    java线程的同步概念是个很有意义的玩意。synchronize从英译过来是"是同时发生"。 但其真正的含义确实截然相反的。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时...
  • java线程同步的实现方式

    千次阅读 2019-03-08 01:47:21
    这里抛砖引玉,为何要使用同步?...下面总结一些java线程实现同步方式,大致有下面几种: 1.同步方法 使用 synchronized关键字,可以修饰普通方法、静态方法,以及语句块。由于java每个对象都有一个内置锁...
  • java线程同步问题,当时线程同步,为什么要锁定当前对象只锁定需要同步的代码不行吗?谁能解释一下为什么?
  • 本文详细介绍了Java线程同步的概念以及常用方法,重点介绍了同步块和同步函数。
  • java的同步容器 在Java中,同步容器主要包括2类: 1)Vector、Stack、HashTable 2)Collections类中提供的静态工厂方法创建的类 Vector实现了List接口,Vector实际上就是一个数组,和ArrayList类似,但是Vector中...
  • Java 线程同步

    千次阅读 2013-11-28 13:17:12
    线程同步就是线程的同步运行,多个线程必须步调一致, 比如缓冲区, 一个线程向缓冲区写入输入, 要求另一个线程必须同步从缓冲区读出数据 如下代码就无法达到这个要去, 因为现在只是对缓冲区锁定了,没有同步 ...
  • JAVA线程同步与死锁

    千次阅读 2018-03-11 17:53:48
    我们已经知道,一个多线程的程序如果是通过Runnable接口实现的,则意味着类中的属性将被多个线程共享,那么这样一来就会出现资源的同步问题。先看2个例子:例1:启用3个售票线程public class ...
  • Java线程(二):线程同步synchronized和volatile

    万次阅读 多人点赞 2012-04-04 10:49:28
    要说明线程同步问题首先要说明Java线程的两个特性,可见性和有序性。多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现。拿上篇博文中的例子来说明,在多个线程之间共享了Count类的一个...
  • Java线程同步解决线程安全理解

    千次阅读 热门讨论 2021-03-02 19:03:32
    ** ** Java中多线程的创建有三种,这里只说两种。 1.继承于Thread类 ①即创建一个Thread的子类 ②重写Thread类中的run()方法,方法体中写线程执行的操作 ③通过子类的对象调用Thread类中的start()方法,通过start()...
  • 线程的同步Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源、什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些原则问题需要考虑,是否有竞争资源被同时改动的问题?...
  • java线程解决同步问题5种方法

    千次阅读 2018-09-10 21:13:09
    实例对象作为单实例传递给Thread 所以创建多个线程共用一个实例对象,里面属性也都是共享。 2. 继承Thread 多线程工作原理: 线程1:操作步骤–工作内存–总内存。 线程2:操作步骤–...
  • Java多线程-线程的同步(同步代码块) 对于同步,除了同步方法外,还可以使用同步代码块,有时候同步代码块会带来比同步方法更好的效果。 追其同步的根本的目的,是控制竞争资源的正确的访问,因此只要在访问...
  • Java线程使用同步锁交替执行打印奇数偶数

    千次阅读 多人点赞 2019-01-14 23:12:14
    对同一个对象进行多线程操作时,如何保证线程执行结果一致性?我们需要对线程操作对象加同步锁。(这是一道面试题) 需求描述 1-20个数字 A线程打印奇数:1,3,5,7,9,11,13,15,17,19 B线程打印偶数:2...
  • Java线程同步队列SynchronousQueue SynchronousQueue是一个没有数据缓冲阻塞队列。生产者线程插入数据(put)必须等待消费者移除数据(take),反之亦然。 SynchronousQueue内部没有维护数据队列,故,开发者不能...
  • 由单例模式优化,引出的java线程数据同步和类加载顺序知识点总结 摘要 几种单例模式优缺点及其改进优化 DCL失效问题原因以及解决 java中线程同步关键字final和volatile java内存屏障 java类...
  • Java线程的同步优化的6种方案

    千次阅读 2020-06-24 17:44:34
    Java中可以使用锁来解决多线程的同步问题,保障了数据的一致性,但也会代理很多问题,本章总结了多线程同步的几种优化方案:包括读写锁、写时复制机制、锁细化等方案。
  • 曾几何时,有多少人听到了多线程就某花一紧,听到了线程的同步就感觉昏昏欲睡。那我们今天就聊一聊我的理解。线程是什么?Java中常用到的新建线程的场景?以及多线程和线程池的概念,最牛逼的还是要说清楚线程的同步...
  • Java线程的同步问题

    千次阅读 2013-05-25 16:58:31
    在多线程的编程环境中,可能会有两个或者更多的线程试图同时访问一个有限的资源。...1、使用synchronized实现多线程的同步 首先我们先举一个大家都熟悉的例子,就是银行取钱的问题,有甲乙两个人同时对一

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,876
精华内容 17,950
关键字:

java线程的同步

java 订阅