你看到一个方法例如public int get()事实上在jvm在执行的时候在执行多个指令来完成的 由于有多个thread在执行 那么这样的操作一定要同步因为多个线程在访问一个共享的数据
解决方案 »
- java正则表达式 截取尖括号中的内容
- 執行緒的問題
- Java关于Applet的问题
- new Object() 问题(不好意思,只能发100)
- 请推荐基本学习java的好书籍(入门)
- int 类型是字长为2字节共16位二进制数,请问将一int数放入byte[]数组里该如何处理
- 如何在JFrame里面指定的地方贴图?
- 我用输出流向文件中写数据,数据只能在一行上连续的写。我想在第二行写数据该用什么方法实现?
- 一段Jtable的代码,编译通过,却不能执行,为什么?代码如下!
- selection change event for combo
- 求助,关于linked list data
- 刚入门,急,寻求数据库开发方面的例子
public synchronied int get()
{
increase();
return a;
}
那么就应该同步了!
想像一下这种情况:
某个客户在使用这个类,要用到里面的变量a
首先使用get方法,假如说得到的是3
然后做其他处理
在该客户处理过程中,其他客户对a进行了修改,即调用increase方法
此时a为4
但第一个客户仍然认为a是3
然后第一个客户调用increase,期望a是4,以便对这种情况做相应操作(假设该客户没有想到会有其他人修改a,因为各个方法只是调用本身是同步的,调用完毕后就不再影响)
结果a的值是5,因此第一个客户得到的结果必然有误想要解决这种情况的问题
只有对操作加锁
就是第一个客户在操作这个类的某个实例(假如这个实例同时被其他客户共享操作)
必须在第一个客户完全操作完成后,其他客户才能调用该实例的方法
也就是第一个客户,在读取a为3,做自己的操作,然后增加a为4,做相应操作,然后返回之前,其他类都不允许访该改类(不仅仅是不允许修改,也不允许读取。读取的话就会发生上面的情况,读的时候是一个数,用的时候成另外一个数了)
这样才能保证所有客户得到的实例是同一个状态注:这跟单例模式不是一个意思,不要弄混了
1 一般的get方法如果需要多次重复从主存中读取,必须要同步,这样会出现数据不一致现象,在本例中不存在这种情况;
2 如果明确规定,读取的数据必须是最新的,需要同步.如果使用get的线程挂起,而set线程该变了数据,那么get得到的还是老数据,对于可以容忍旧数据的程序来是可以的对于本例(本人认为不合理),本人认为get可以不要同步,望大侠们发言....
而且问题中的同步也是无效的,对一个方法加上syncronize根本不起作用.
{
private int a; public int get()
{
increase();
System.out.print("{ a= " + a);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.print(" } ");
return a;
}
public synchronized int getBySync()
{
return get();
}
public void increase()
{
a++;
}
}class Caller implements Runnable
{
String msg;
ClassA a;
Thread thread;
public Caller(ClassA a)
{
this.a = a;
thread = new Thread(this);
thread.start();
}
public void run()
{
a.get();
}
}class CallerBySync implements Runnable
{
String msg;
ClassA a;
Thread thread;
public CallerBySync(ClassA a)
{
this.a = a;
thread = new Thread(this);
thread.start();
}
public void run()
{
a.getBySync();
}
}class Test
{
private void test()
{
ClassA a = new ClassA();
Caller c1 = new Caller(a);
Caller c2 = new Caller(a);
Caller c3 = new Caller(a);
try
{
c1.thread.join();
c2.thread.join();
c3.thread.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
private void testBySync()
{
ClassA a = new ClassA();
CallerBySync c1 = new CallerBySync(a);
CallerBySync c2 = new CallerBySync(a);
CallerBySync c3 = new CallerBySync(a);
try
{
c1.thread.join();
c2.thread.join();
c3.thread.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
Test t = new Test();
t.test();
System.out.println("以下是使用同步的不同");
t.testBySync();
}
}
{ a= 1{ a= 2{ a= 3 } } } 以下是使用同步的不同
{ a= 1 } { a= 2 } { a= 3 } Press any key to continue...t.test() 没有阻止三个线程同时调用同一对象的同一方法的方法存在。
t.testBySync()通过线程同步防止了在一个线程使用getBySync()即get()时其它线程进入该方法。
通过synchronized防止状态出现竞争。