Java中的同步行为不正确?
发生什么事了 线程期间的同步列表不应该在最后停止println吗 只有在主线程的Java中的同步行为不正确?,java,multithreading,list,concurrency,synchronization,Java,Multithreading,List,Concurrency,Synchronization,发生什么事了 线程期间的同步列表不应该在最后停止println吗 只有在主线程的synchronized(list)语句执行之前,第二个线程的run()方法的执行(特别是其中的synchronized(list)语句的执行)才是如此 调用thread.start()在synchronized(list){System.out.println(list);}之前,不保证第二个线程将在执行synchronized(list){System.out.println(list);}之前开始运行 线程期间
synchronized(list)
语句执行之前,第二个线程的run()
方法的执行(特别是其中的synchronized(list)
语句的执行)才是如此
调用thread.start()
在synchronized(list){System.out.println(list);}
之前,不保证第二个线程将在执行synchronized(list){System.out.println(list);}
之前开始运行
线程期间的同步列表不应该在最后停止println吗
只有在主线程的synchronized(list)
语句执行之前,第二个线程的run()
方法的执行(特别是其中的synchronized(list)
语句的执行)才是如此
调用thread.start()
在synchronized(list){System.out.println(list);}
之前,不保证第二个线程将在执行synchronized(list){System.out.println(list);}
之前开始运行
我现在不明白的是,打印输出不包含
“测试3”。线程期间同步列表不应该停止
最后是println吗
这意味着您启动的线程将在主线程之前获得锁。在Java中无法保证这一点。事实上,它似乎是反过来工作的,主线程在第二个线程之前获取锁,阻止第二个线程获取锁
您可以尝试使用wait/notify机制来确保主线程正在等待另一个线程终止:
导入java.util.ArrayList
Thread.sleep();
list.add("test3");
println(list);
for(int i=0;i<3;i++){
列表。添加(“测试”+i);
}
Thread Thread=新线程(new Runnable(){
@凌驾
公开募捐{
已同步(列表){
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
列表。添加(“测试3”);
//通知主线程
list.notify();
}
}
});
thread.start();
已同步(列表){
试一试{
//在指定的时间内等待另一个线程终止
//这将临时释放第二个线程的锁。
列表。等待(5000);
}捕捉(中断异常e){
//见上文。。
e、 printStackTrace();
}
系统输出打印项次(列表);
}
我现在不明白的是,打印输出不包含
“测试3”。线程期间同步列表不应该停止
最后是println吗
这意味着您启动的线程将在主线程之前获得锁。在Java中无法保证这一点。事实上,它似乎是反过来工作的,主线程在第二个线程之前获取锁,阻止第二个线程获取锁
您可以尝试使用wait/notify机制来确保主线程正在等待另一个线程终止:
导入java.util.ArrayList
Thread.sleep();
list.add("test3");
println(list);
for(int i=0;i<3;i++){
列表。添加(“测试”+i);
}
Thread Thread=新线程(new Runnable(){
@凌驾
公开募捐{
已同步(列表){
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
列表。添加(“测试3”);
//通知主线程
list.notify();
}
}
});
thread.start();
已同步(列表){
试一试{
//在指定的时间内等待另一个线程终止
//这将临时释放第二个线程的锁。
列表。等待(5000);
}捕捉(中断异常e){
//见上文。。
e、 printStackTrace();
}
系统输出打印项次(列表);
}
>“不,同步将以任何顺序授予访问权限”-..>“不,同步将以任何顺序授予访问权限”----我可以通过什么方式确定多线程的执行顺序,以确保不存在并发修改问题?例如,如果我在一个ArrayList中循环,并且在该ArrayList中循环,那么它将发送一个数据包。数据包返回断开的管道,ArrayList中的“Object”被“Object”线程删除。如何确保在删除发送断开管道的对象之前完成循环?@JustinQuach您的用例还不够清楚,但也许您可以使用一些并发集合(例如CopyOnWriteArrayList)。您可以使用诸如Condition
或ReadWriteLock
之类的类来等待线程。如果您的用例更简单,那么还有哪些方法可以确定多线程的执行顺序,以确保不存在并发修改问题?例如,如果我在一个ArrayList中循环,并且在该ArrayList中循环,那么它将发送一个数据包。数据包返回断开的管道,ArrayList中的“Object”被“Object”线程删除。如何确保在删除发送断开管道的对象之前完成循环?@JustinQuach您的用例还不够清楚,但也许您可以使用一些并发集合(例如CopyOnWriteArrayList)。您可以使用诸如Condition
或ReadWriteLock
之类的类来等待线程。如果您的用例更简单,那么还有
for (int i = 0; i < 3; i++) {
list.add("test" + i);
}
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (list) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add("test3");
// Notify the main thread
list.notify();
}
}
});
thread.start();
synchronized (list) {
try {
// wait for the other thread for a specified time to terminate
// this will temporary release the lock for the second thread.
list.wait(5000);
} catch (InterruptedException e) {
// see above..
e.printStackTrace();
}
System.out.println(list);
}