在java中测试同步
这里我拿了一个字符串锁进行测试,以了解两个线程的实际流量 行为,但它给我不可预知的输出 这是代码在java中测试同步,java,multithreading,synchronize,Java,Multithreading,Synchronize,这里我拿了一个字符串锁进行测试,以了解两个线程的实际流量 行为,但它给我不可预知的输出 这是代码 public class SyncCall {static SyncTesting sync1 = new SyncTesting(); static Runnable r1=new Runnable() { public void run() { try { sync1.s=new String("15"); Thr
public class SyncCall {static SyncTesting sync1 = new SyncTesting();
static Runnable r1=new Runnable() {
public void run() {
try {
sync1.s=new String("15");
Thread.currentThread().setName("Thread1");
sync1.testme();
// Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
System.out.println("sync1");
} catch (Exception ex) {
Logger.getLogger(SyncCall.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
static Runnable r2=new Runnable() {
public void run() {
try {
sync1.s=new String("17");
Thread.currentThread().setName("Thread2");
sync1.testme();
//Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
System.out.println("sync2");
} catch (Exception ex) {
Logger.getLogger(SyncCall.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
public static void main(String args[]){
Thread th1=new Thread(r1);
Thread th2=new Thread(r2);
th1.start();
th2.start();
}
}
}
我得到的输出有时像
你好
17
你好
17
你好,在睡后1
螺纹1
同步1
睡后你好2
螺纹2
同步2
有时候
你好
15
你好
15
睡后你好2
螺纹2
同步2
你好,在睡后1
螺纹1
同步1
我知道我得到的不同的输出是因为字符串对象在同步中是一个锁,但是我想知道为什么两个线程给出了相同的字符串值,而另一个线程给出了相同的字符串值
线程更改该字符串值。我猜如果第二个线程在第一个线程使用它之前更改该值,它将保持更改状态,否则第二个线程将首先设置该值,而第一个线程更改该值。时间轴选项1-可能以任意顺序发生(15个优先或17个优先)
- r1:将s设置为15
- r2:将s设置为17
- r1:使用17输入锁
- r2:使用17进入锁定被阻止
- r1:出口锁
- r2:进入锁
- r2:出口锁
- r1:将s设置为15
- r1:使用15输入锁
- r2:将s设置为17
- r2:使用17输入lock(未被阻止,因为lock的值不同)
- r1:出口锁
- r2:出口锁
T1 --> sets S=15 --->enters Syn Block --> prints Hello --> prints S (T2 has set S=17)
T2 -------------> sets S=17 --->enters Syn Block --> print Hello --> prints S
T1 ------------> sets S=15 --->enters Syn Block --> prints Hello --> prints S
T2 --> sets S=17 ---> enters Syn Block --> print Hello --> prints S (S=15 set before T2 prints S)
打印相同的S值(15)时
T1 --> sets S=15 --->enters Syn Block --> prints Hello --> prints S (T2 has set S=17)
T2 -------------> sets S=17 --->enters Syn Block --> print Hello --> prints S
T1 ------------> sets S=15 --->enters Syn Block --> prints Hello --> prints S
T2 --> sets S=17 ---> enters Syn Block --> print Hello --> prints S (S=15 set before T2 prints S)
打印差异值时
T1 --> sets S=15 --->enters Syn Block --> prints Hello --> prints S
T2 -----------------------------------------------------------------> sets S=17 --->enters Syn Block --> print Hello --> prints S
这里的问题是更改锁对象本身。因此,两个线程可以执行相同的代码块,即使它的sync有太多错误,以至于很难知道从哪里开始。
同步。您正在对完全不同的对象调用testme
,它们永远不会交互
新字符串(“abc”)
是不正确的对象用法。在String
上调用new
可以保证实例将不相同,即使对于相同的数据也是如此<代码>字符串a=新字符串(“abc”);字符串b=新字符串(“abc”);a==b为假
synchronized
块中使用同一锁定对象的完全相同的实例,这应该是非常明显的,否则它怎么知道要阻止访问什么
volatile
,否则线程可能会或可能不会看到数据的更新
AtmoicInteger
线程
了解如何使用执行器服务