哪些需要修改变量需要同步的,就用synchronized关键字修饰
package com.ehealth.thread;
class foo{
private int x=100;
public int getX(){
return x;
}
public synchronized int fix(int y){
x=x-y;
System.out.println("Thread :"+Thread.currentThread().getName()+ " Thread end ,it take away :"+y +" now ,the value is "+x);
return x;
}
}
class MyThread extends Thread{
private foo f;
private int y=0;
MyThread(String name,foo f,int y){
super(name);
this.f=f;
this.y=y;
}
public void run(){
f.fix(y);
}
}
public class LockTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
foo f=new foo();
MyThread m1=new MyThread("Thread-A",f,10);
MyThread m2=new MyThread("Thread-B",f,2);
MyThread m3=new MyThread("Thread-C",f,-3);
MyThread m4=new MyThread("Thread-D",f,5);
m1.start();
m2.start();
m3.start();
m4.start();
}
}
上面代码的理解:
首先,我们创建一个要多个线程进行修改的对象的类
接着我们要创建一个线程类。在这个类中,我们先要私有一个实例对象的引用。然后,在实例化线程的时候,把真正创建的修改对象传进去。这时候。所有的操作就针对这个对象而言。因为使用了关键字。所以会同步数据
锁的原理:
Java中每个对象都有一个内置的锁。
有以下几个要点:
1)只能同步方法,不能同步类或者变量
2)应该清楚在哪个对象上进行同步
3)如果有两个线程要执行同一个对象的synchronized方法。那么只有一个线程可以执行这个方法,另外的线程要等待。
线程同步小结
1、线程同步的目的是为了保护多个线程访问一个资源时对资源的破坏。
2、线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他同步方法。
3、对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。
4、对于同步,要时刻清醒在哪个对象上同步,这是关键。
5、编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对“原子”操作做出分析,并保证原子操作期间别的线程无法访问竞争资源。
6、当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。
7、死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小。真让你写个死锁程序,不一定好使,呵呵。但是,一旦程序发生死锁,程序将死掉。
转载于:https://blog.51cto.com/ehealth/1723219