Java 为什么我的线程不同步?
我试图掌握同步线程,但我不理解我遇到的问题 有人能帮我诊断一下吗?或者,更好的是,解释一下我如何为自己诊断Java 为什么我的线程不同步?,java,multithreading,synchronization,Java,Multithreading,Synchronization,我试图掌握同步线程,但我不理解我遇到的问题 有人能帮我诊断一下吗?或者,更好的是,解释一下我如何为自己诊断 import java.util.ArrayList; import java.util.List; import java.util.concurrent.CyclicBarrier; public class Controller { public static void main(String[] args) { int numThreads = 0;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
public class Controller {
public static void main(String[] args) {
int numThreads = 0;
List<Thread> threads = new ArrayList<>();
if (args.length > 0) {
numThreads = Integer.parseInt(args[0]);
}
else {
System.out.println("No arguments");
System.exit(1);
}
CyclicBarrier barrier = new CyclicBarrier(numThreads);
int arr[][] = new int[10][10];
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(new ThreadableClass(barrier, arr));
threads.add(newThread);
}
for (Thread thread : threads) {
thread.start();
}
}
}
相反,所有线程都会增加数组,并开始相互打印 结果没有什么出人意料的。创建n个线程。你告诉所有的线程开始。每个threads run()都以以下内容开头:
long threadId = Thread.currentThread().getId();
System.out.println(threadId + " Starting");
...changeArray();
将更改该共享阵列写入阵列后,尝试同步(在该屏障上)。那太晚了
关键是:您有10个不同的ThreadableClass实例。每一个都在自己的上运行!synchronized
关键字。。。这里根本不提供任何保护
因为:synchronized可防止两个不同的线程对同一对象调用同一方法。但是当你有多个对象,并且你的线程在那些不同的对象上调用该方法时,就会出现锁定!您的代码可以归结为:
threadA to call changeArray() .. on itself
threadB to call changeArray() .. on itself
threadC to call changeArray() .. on itself
换言之:您给n个线程访问该共享阵列的权限。但是您允许这n个线程同时进入changeArray()
一个简单的解决方案;改变
private synchronized void changeArray() {
到
换句话说:确保n个线程必须在相同的监视器上锁定;在这种情况下,共享数组
或者:不要在ThreadableClass中创建changeArray()
方法。。。创建一个类
ArrayUpdater {
int arr[] to update
synchronized changeArray() ...
然后创建该类的一个实例;并为每个线程提供相同的实例。现在sync'ed方法将阻止多个线程进入 结果没有什么出人意料的。创建n个线程。你告诉所有的线程开始。每个threads run()都以以下内容开头:
long threadId = Thread.currentThread().getId();
System.out.println(threadId + " Starting");
...changeArray();
将更改该共享阵列写入阵列后,尝试同步(在该屏障上)。那太晚了
关键是:您有10个不同的ThreadableClass实例。每一个都在自己的上运行!synchronized
关键字。。。这里根本不提供任何保护
因为:synchronized可防止两个不同的线程对同一对象调用同一方法。但是当你有多个对象,并且你的线程在那些不同的对象上调用该方法时,就会出现锁定!您的代码可以归结为:
threadA to call changeArray() .. on itself
threadB to call changeArray() .. on itself
threadC to call changeArray() .. on itself
换言之:您给n个线程访问该共享阵列的权限。但是您允许这n个线程同时进入changeArray()
一个简单的解决方案;改变
private synchronized void changeArray() {
到
换句话说:确保n个线程必须在相同的监视器上锁定;在这种情况下,共享数组
或者:不要在ThreadableClass中创建changeArray()
方法。。。创建一个类
ArrayUpdater {
int arr[] to update
synchronized changeArray() ...
然后创建该类的一个实例;并为每个线程提供相同的实例。现在sync'ed方法将阻止多个线程进入 因为您使用
新线程类(barrier,arr)
为每个theard提供新的实例,所以基本上,所有TheADR都使用不同的线程类
对象,所以您的代码同步方法并行运行,因此,您需要使用单个ThreadableClass
对象,如下所示:
ThreadableClass threadableClass= new ThreadableClass(barrier, arr);
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(threadableClass);
threads.add(newThread);
}
ThreadableClass ThreadableClass=新的ThreadableClass(屏障,arr);
for(int i=0;i
重要的一点是,同步是一次为单个线程提供对对象的访问(即密钥)。如果您为每个线程使用不同的对象,线程不会等待密钥,因为每个线程都有自己的密钥(如您的示例中所示)。因为您使用新的ThreadableClass(barrier,arr)
为每个线程提供新的实例,所有TheADR都使用不同的ThreadableClass
对象,因此您的代码同步方法并行运行,因此您需要使用单个ThreadableClass
对象,如下所示:
ThreadableClass threadableClass= new ThreadableClass(barrier, arr);
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(threadableClass);
threads.add(newThread);
}
ThreadableClass ThreadableClass=新的ThreadableClass(屏障,arr);
for(int i=0;i
重要的一点是,同步是一次为单个线程提供对对象的访问(即密钥)。如果您对每个线程使用不同的对象,线程不会等待密钥,因为每个线程都有自己的密钥(如您的示例中所示)。。非常感谢你。我现在明白了。通过阅读您的解决方案,我决定在Contoller类中创建ThreadableClass的单个实例,然后将每个线程传递给同一个实例。(只是想给下一个人提供一些额外的背景,让他思考同样的事情)。再次感谢鬼猫!你真的帮了大忙。既然你似乎知道你在这些地方做些什么,我应该在风格上做些什么改进吗?有什么我不应该遵守的习俗吗?(生日快乐!!!)就几个;因为我马上就要睡觉了;-)A) 即使使用静态主控灯;试着在那里做尽可能少的事情。比如:编写一个方法,该方法接受该数字“n”,并创建一个线程列表;还有另一种方法继续对它们起作用。您只需读取数字,然后调用这些方法。B) 尝试将字段设置为最终字段,以便编译器可以帮助您确保