如果一个static方法被标注为synchronized,是否意味者它在同一时间不能被两个不同线程的调用?即使这个类被实例化多次?举例说类A:
Class A {
public A() {}
public synchronized static method() {
}
}那么是否以下的各种调用都不会同时出现,而是排队等候前面的执行结束?A.method();
A object1 = new A();
object1.method();
A object2 = new A();
object2.method();多谢!
Class A {
public A() {}
public synchronized static method() {
}
}那么是否以下的各种调用都不会同时出现,而是排队等候前面的执行结束?A.method();
A object1 = new A();
object1.method();
A object2 = new A();
object2.method();多谢!
解决方案 »
- 求详细软件人员的划分
- 求 前15000够被2或者3或者5所整除的 算法
- 大哥们!!帮帮忙啊!我不知道到底哪里出错了?
- [在线等]请教一个简单的UDP传输程序的问题
- 写回文件时,可以选择文件中的某一行进行output吗??急,在线等!!谢
- 字体设置
- Java中与XML有关的类有哪些?
- 请教高手一个“3W行代码工程量的CS结构聊天系统的”“单元测试”和“集成测试”的方法问题...
- 一个java的简单问题,你肯定可以得到这20分!
- 请问,谁知道,为什么我装好了JBUILDER5以后,在TOOLS菜单里,很多项都是灰的??????
- 能否用JAVA画出颜色渐变,文字阴影,图形阴影等,谢谢
- ant如何copy几个文件到 .jar文件中,而不覆盖jar包中其他的文件
一个设置了synchronized关键字的方法自动成为同步方法
进入方法则相当于以当前对象为信号量,上锁。退出时解锁。
Java还提供了wait()和notify(),notifyAll()方法辅助进行同步
wait()会解锁当前的信号量,使线程进入堵塞状态。直到使用
同一信号量的notify()或notifyAll()来唤醒它。 线程在不同时刻有不同的状态,正在被执行时,即占有CPU时
我们称之为Running状态。那么其它的状态线程自然是不能运行啦。
很可能有多个线程都不能运行吧,但它们不能运行的原因却是各不相同的。
那么由于相同原因不能运行的线程就会存在一个“池pool”中。
由于虚拟机线程调度而不运行的,处于 Runnable池中,表示万事俱备,
只差CPU,由于使用synchronized而阻塞的线程就会在对象锁
(object's lock pool)池中等待。而同步的方法中调用wait()后,线程则会
在wait池中等待。这里要注意了,首先wait()方法能得到执行说明当前线程
正在运行(在Running状态),从而说明它肯定拥有对象锁;第二,调用
wait()方法进入阻塞状态时,当前线程将释放对象锁(!!)第三,
在notify()或notifyAll()方法唤醒此线程时,它将进入 object's lock pool
池中等待,以重新获得对象锁。状态图如下所示。
Schedule
(Runnable) <-------------> (Running)
^ | \
| | --\
| synchronized wait() --must hav lock
acquire lock | \ release lock
| | \
| | \
| (Blocked in) | (Bolcked in )
----------( object's )<---- ( object's )
( lock pool) <---------- ( wait pool )
notify()
synchronized void f() { /* ... */ }
synchronized void g() { /* ... */ }
每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分(不必为此写任何特殊的代码)。调用任何synchronized方法时,对象就会被锁定,不可再调用那个对象的其他任何synchronized方法,除非第一个方法完成了自己的工作,并解除锁定。在上面的例子中,如果为一个对象调用f(),便不能再为同样的对象调用g(),除非f()完成并解除锁定。因此,一个特定对象的所有synchronized方法都共享着一把锁,而且这把锁能防止多个方法对通用内存同时进行写操作(比如同时有多个线程)。
每个类也有自己的一把锁(作为类的Class对象的一部分),所以synchronized static方法可在一个类的范围内被相互间锁定起来,防止与static数据的接触。
对于:
Class A {
public A() {}
public synchronized static method1() {}
public synchronized static method2() {}
}
是否A.method1()和A.method2()都是不能同时被同时调用的?(会遵循请求的先后顺序,依次执行?)
我觉得不太对的,比如我现在想对static数据锁定,那你不是等于说 这样不可能实现了吗?
Class A {
public A() {}
public synchronized static method1() {}
public synchronized static method2() {}
}
class m1 extends thread{
while(true){
A.method1();
}
}
class m2 extends thread{
while(true){
A.method2();
}
}main(){
m1.start();
m2.start();
}class A 的两个方法可以同时被调用,如果thread m2也调用a.method1()的话,将按调用顺序执行,可以肯定m1和m2中有一个不会执行了。
回:某一时刻,该类的所有sync静态方法只有一个在运行?
在某一时刻,该类的所有sync静态方法都可以被执行,但每个sync方法只有一个thread在执行(调用)它。
我在java1.4上试的结果证实这个说法是错误的!
try it yourself!!
Class A {
public A() {}
public synchronized static method1() { do a dead circle }
public synchronized static method2() { do a dead circle }
}
} public static synchronized void method1() {
System.out.println("Start method 1");
while(true);
} public static synchronized void method2() {
System.out.println("Start method 2");
while(true);
}
}public class Thread1 extends Thread { public Thread1() {
} public void run() {
//StaticClass.method1();
StaticClass sc = new StaticClass();
sc.method1();
}
}public class Thread2 extends Thread { public Thread2() {
} public void run() {
//StaticClass.method2();
StaticClass sc = new StaticClass();
sc.method2();
}
}public class ThreadRunTester {
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
}
}结果只打出一行信息,不知道你的测试代码是什么样的。另外我测试了1.3和1.4,结果是一致的。
public static synchronized void method1() {
while(true){
System.out.print("A");
Thread.currentThread.sleep(100);
}
}
public static synchronized void method2() {
while(true){
System.out.print("B");
Thread.currentThread.sleep(100);
}
}结果是A和B交替出现!
import java.io.*;public class SyncTest extends Thread
{
int whichfunc=0;
public static void main(String [] args)throws Exception
{
SyncTest syn1=new SyncTest(1);
SyncTest syn2=new SyncTest(2);
syn1.join();
syn2.join();
}
public SyncTest(int which)
{
whichfunc=which;
start();
}
public void run()
{
try{
if(whichfunc==1){
func1();
}
else if(whichfunc==2)
{
func2();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static int order=0;
private synchronized static void func1()throws Exception
{
System.out.println("this is func1,value is "+order++);
Thread.sleep(2000);
System.out.println("end of func1,value is "+order);
}
private synchronized static void func2()throws Exception
{
System.out.println("this is func2,value is "+order++);
Thread.sleep(2000);
System.out.println("end of func2,value is "+order);
}
}
对比func1和func2
如果两着都是synchronized static 则两者被同步
如果两者都只是static 而不是synchronized,则不能被同步如果两者都只是synchronized而不是static 也不能被同步,因为他们不是同一对象的方法。如果两者都是synchronized,但是有一个不是static 而另一个是,
也不能被同步所以我认为synchronized作用在static方法前的时候,是对特定的Class对象在全局中同步。
synchronized作用在非static方法前的时候,是对特定的对象同步。
http://www.javaworld.com/javaworld/jw-04-1999/jw-04-toolbox.html
例如对于上面两个例子中func1改为
private void func1()throws Exception
{
synchronized(this.getClass())
{
System.out.println("this is func1,value is "+order++);
Thread.sleep(2000);
System.out.println("end of func1,value is "+order);
}
}
效果是一样的。
sync和static方法并没有任何联系,把sync和static分开看作两个特性来看就简单多了。被sync的方法和块在某一时刻只有一个thread在调用他。static的变量和方法和类在整个jvm中只有一个。
非static 方法是必须有所依托的对象的,而static方法在语义上是不需要有一个对象。synchronized 有作用域的问题,不是对整个JVM都有效,这一点必须明白。
synchronized 实际上是对一个锁的加琐和释放的问题。对非static方法,synchronized的作用隅只是所依托的对象而不是全局唯一的,而 static 方法synchronized作用域是类的Class对象,由于这个对象是全局唯一的,所以static 方法是一个时候只能有一个访问他。在这种意义上我猛也可以把static 方法看看成是非static的方法,只不过是一个Class对象的方法。
因此sync同static 是有关系的。
被sync的方法和块在某一时刻只有一个thread在调用他???
当两个对象实例线程调用一个sync的非static方法时候,sync不起任何作用,这是经过理论和实践检验的。
class ThreadA {
/**
* @param args
*/
/**
* @param args
*/
public static void main(String[] args) {
Thread b = new Thread(new ThreadA());
//ThreadA b = new ThreadA();
b.start();
Object obj = new Object();
System.out.println("b is start...."); Thread c = new Thread();
c.start();
synchronized (c)// 括号里的b是什么意思,起什么作用?
{
try {
//Thread.sleep(20);
//b.setTotal();
System.out.println("Waiting for b to complete...");
c.wait();// 这一句是什么意思,究竟让谁wait?
System.out.println("Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
}
}
public class ThreadA implements Runnable {
public int total;
public void setTotal(){
total++;
}
public void run(){
synchronized (this) {
System.out.println("ThreadA is running..");
/*try{
Thread.sleep(1000);
}catch(InterruptedException e){}*/
for (int i = 0; i < 20; i++) {
total += i;
System.out.println("total is " + total);
}
notify();
}
}}