额。。我想说我自己的怎么跑出来这么多人 我去跑过代码了,也分析了原因。有些改动。先代码import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class SynchronizedTest { public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); A a = new A(); B b = new B(a); C c = new C(a); es.submit(b); es.submit(c); }
}class A{ private List<Integer> messages = new ArrayList<Integer>();
public void add(int message){ synchronized(messages){ messages.add(message); } }
public List<Integer> getMessages() { return messages; } public void setMessages(List<Integer> messages) { this.messages = messages; } public void dothis(){ synchronized(messages){ try { System.out.println(messages); Thread.sleep(1000); System.out.println("now" + messages); messages.clear(); } catch (InterruptedException e) { e.printStackTrace(); } } } }class B implements Runnable{ private A a; public B(A a){ this.a = a; } @Override public void run() { System.out.println("start thread b"); a.dothis(); } }class C implements Runnable{ private A a; public C(A a){ this.a = a; } @Override public void run() { System.out.println("start Thread c"); a.add(1); a.add(2); System.out.println("next Thread "+ a.getMessages()); } 原因很简单,2楼所说的synchronized的使用方法好像也是不行的,同样需要在add方法上添加synchronized 但是呢,Thinking in Java比较推荐的是楼主原先的方法,于是我就按照楼主的方法来改了。 楼主的这种锁的机制在于,只有在使用synchronized的地方才对被synchronized持有的变量进行检测,看是否被其他线程掌握了。 你只有dothis中检测,但是你的C不执行dothis,而是add所以我在add中添加了synchronized语句楼主可以试下我的代码
然后C就执行2步add啊
我不明白楼主纠结所在?
run里面只是线程要执行的序列,不代表该进程要一直跑,跑完了重新跑,再跑是不是这么一说来着,楼下继续
public synchronized void dothis(messages){
try {
Thread.sleep(4000);
System.out.println(messages);
messages.clear();
} catch (InterruptedException e) {
e.printStackTrace();
}
}改一下,看这样行不?
C 执行add的时候,message对象已经被锁住了,按理说应该被锁住的,为什么还能继续操作?
其他方法貌似可行的,只是工作需求只想把messages对象锁住。 ,但是就是搞不懂为什么锁不住对象。
我去跑过代码了,也分析了原因。有些改动。先代码import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class SynchronizedTest {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
A a = new A();
B b = new B(a);
C c = new C(a);
es.submit(b);
es.submit(c);
}
}class A{
private List<Integer> messages = new ArrayList<Integer>();
public void add(int message){
synchronized(messages){
messages.add(message);
}
}
public List<Integer> getMessages() {
return messages;
} public void setMessages(List<Integer> messages) {
this.messages = messages;
} public void dothis(){
synchronized(messages){
try {
System.out.println(messages);
Thread.sleep(1000);
System.out.println("now" + messages);
messages.clear();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}class B implements Runnable{
private A a;
public B(A a){
this.a = a;
}
@Override
public void run() {
System.out.println("start thread b");
a.dothis();
}
}class C implements Runnable{
private A a;
public C(A a){
this.a = a;
}
@Override
public void run() {
System.out.println("start Thread c");
a.add(1);
a.add(2);
System.out.println("next Thread "+ a.getMessages());
}
原因很简单,2楼所说的synchronized的使用方法好像也是不行的,同样需要在add方法上添加synchronized
但是呢,Thinking in Java比较推荐的是楼主原先的方法,于是我就按照楼主的方法来改了。
楼主的这种锁的机制在于,只有在使用synchronized的地方才对被synchronized持有的变量进行检测,看是否被其他线程掌握了。
你只有dothis中检测,但是你的C不执行dothis,而是add所以我在add中添加了synchronized语句楼主可以试下我的代码