我正在阅读一本关于线程/同步的简单示例,该书声称使用synchronized
会允许在同一实例上调用一个线程来访问该方法。它确实按照承诺进行了序列化,但似乎Caller
在Synch
main
下面的方法中创建的第三个数组的大约9/10倍于第二个数组。该代码是示例代码,显示了没有同步方法的问题。
class CallMe {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("CallMe Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable {
String msg;
CallMe target;
Thread t;
public Caller (CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread(this);
t.start();
}
@Override
public void run() {
target.call(msg);
}
}
class Synch {
public static void main(String args[]) {
CallMe target = new CallMe();
Caller c1 = new Caller(target, "Hello");
Caller c2 = new Caller(target, "Synchronized");
Caller c3 = new Caller(target, "World");
try {
c1.t.join();
c2.t.join();
c3.t.join();
} catch (InterruptedException e) {
System.out.println("Synch Interrupted");
}
}
}
这本书说明了两种方式来处理这个问题,他们是-
synchronized void call(String msg) {...}
并且
public void run() { synchronized (target) {...} }
很显然,这两种选择工作,因为,相对于原来的代码,括号内的字都像一致…
[您好]
[世界](大约90%的电话回退时间)
[已同步](1 /许多已同步为第一个味精)
…原始代码没有韵律或理由。因此,我知道它是“有效的”,可以通过在每个Caller
实例上放置断点直接看到它。每当我这样做时,对我来说,它每次都有效。
为什么第三个在第二个之前Caller
始终调用call
?
根据定义,线程是并行运行的,并且没有任何优先级高于其他线程。
一旦线程全部启动,本质上是随机的,它将首先运行,通常,第一个启动的线程将具有轻微的“领先优势”,但是与启动线程等的开销相比,该优势很小。
您的特定环境的怪癖恰好偏向于使用一个线程,结果在不同的系统上可能会有所不同,因此当然不应该依赖它。
顺便说一句,这是不好的做法,原因有很多:
public Caller (CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread(this);
t.start();
}
(实际上您可能会收到编译器警告)。
更好的是提供一种启动方法
public Caller start() {
t.start();
return this;
}
然后做
new Caller(target, msg).start();
这绝对可以确保Thread对象开始处理之前,Caller对象已完全初始化并准备就绪。
问题内容: 我有以下查询: 我有以下问题: USING语法与ON语法同义吗? 这些联接是从左到右评估的吗?换句话说,此查询是否说:x =公司加入了用户;y = x JOIN工作;z = y加入用户帐户; 如果对问题2的回答为“是”,那么可以安全地假设“公司”表中包含“公司ID”,“用户ID”和“工作ID”列? 我不明白在引用别名“ j”时,如何使用WHERE子句来选择公司表上的行 任何帮助,将不胜
我有2个子项目的java项目。像这样的结构 我只需要在root buiild.gradle中创建'deploy'任务,然后执行以下操作: null 我看到错误“no-source”,但是文件夹“client/build/libs”和“server/build/libs”存在并包含jar。我可以肯定,因为手动运行任务‘复制文件’创建文件夹‘目标’和复制所有文件。我看到的唯一可能的选项是“复制文件”任
问题内容: 原始问题: 当我的JavaScript调用的功能在页面下方而不是在调用页面的下方定义时,JSHint会抱怨。但是,我的页面是用于游戏的,在下载全部内容之前,不会调用任何函数。那么为什么订单功能出现在我的代码中很重要? 我在里面吟。看来我需要花另一天的时间才能重新排序六千行代码。使用javascript的学习曲线一点也不陡峭,但是非常糟糕。 问题答案: tl; dr 如果在加载完成之前不
问题内容: 我担心给出的文件和目录的顺序。如果我有这些目录,,,,,,,,,,,,,什么是输出列表的顺序? 它是按数值排序的吗? 或按ASCII值排序,如? 此外,如何获得特定的排序? 问题答案: 用途。这是的文档字符串: listdir(路径)-> list_of_strings 返回一个列表,其中包含目录中条目的名称。 该列表按任意顺序排列 。它不包括特殊条目“。” 和“ ..”,即使它们存在
问题内容: 我有一个导航栏作为地图: 其中具有各种属性,子项等。当我尝试渲染导航栏(带有)时,它以随机顺序显示。我知道它在运行时会随机排序,但是似乎无法获取有序的键列表或按插入顺序进行迭代。 游乐场链接位于此处:http : //play.golang.org/p/nSL1zhadg5,尽管它似乎没有表现出相同的行为。 如何在不破坏插入顺序的情况下迭代此映射? 问题答案: Go地图不保持插入顺序;
我对Cumber框架没有什么顾虑:-1。我有一个功能文件(步骤相互依赖),我想按顺序运行所有场景,默认情况下它们是按随机顺序运行的。2.如何多次运行单个功能文件? 我贴上一些标签,试着跑,但没有运气。 因此,在上面的步骤中,我从一个步骤中获取令牌,并尝试在另一个步骤中打印令牌,但我得到的是null,而不是实际值,因为我的步骤是随机的。请注意,我正在通过testng运行TestRunner。xml文