Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的同步行为不正确?_Java_Multithreading_List_Concurrency_Synchronization - Fatal编程技术网

Java中的同步行为不正确?

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);}之前开始运行 线程期间

发生什么事了

线程期间的同步列表不应该在最后停止println吗

只有在主线程的
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);
    }