考虑以下代码
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
</LinearLayout>
</TabHost>
第一次运行的代码输出:
public class TestThreads {
public static void printListOfStrings(Collection<String> cs) {
for (String str : cs)
System.out.print(str + " by " + Thread.currentThread().getName());
System.out.println();
}
public static void main(String[] args) {
final List<String> lt1 = new ArrayList<>();
for (int i = 0; i < 5; i++)
lt1.add("string 1");
Thread thread1 = new Thread(" ONE ") {
@Override
public void run() {
printListOfStrings(lt1);
}
};
thread1.start();
final List<String> lt2 = new ArrayList<>();
for (int i = 0; i < 5; i++)
lt2.add("string 2");
Thread thread2 = new Thread(" TWO ") {
@Override
public void run() {
printListOfStrings(lt2);
}
};
thread2.start();
final List<String> lt3 = new ArrayList<>();
for (int i = 0; i < 5; i++)
lt3.add("string 1");
Thread thread3 = new Thread(" THREE ") {
@Override
public void run() {
printListOfStrings(lt3);
}
};
thread3.start();
}
}
第二次运行:
string 1 by ONE string 1 by ONE string 1 by ONE string 1 by ONE string 2 by TWO string 1 by ONE string 1 by THREE
string 2 by TWO string 2 by TWO string 2 by TWO string 2 by TWO
现在谈到这一点,当Thread ONE和Thread TWO同时在 string 2 by TWO string 1 by THREE string 1 by ONE string 1 by THREE string 2 by TWO string 1 by THREE string 1 by ONE string 1 by THREE string 2 by TWO string 1 by THREE string 1 by ONE
string 2 by TWO string 2 by TWO
string 1 by ONE string 1 by ONE
string 1 by THREE string 1 by THREE string 1 by THREE string 1 by THREE
方法中运行for循环时,我没有问题。但是,与线程A具有相同字符串列表的Thread THREE不应该与线程A一起运行。如果线程A在线程C之前启动,则应该允许A在C等待它完成时执行,或者如果线程C是在A之前启动,应该允许C执行而A等待C完成。我应该在printListOfStrings()
方法中添加什么来实现这一点。提前谢谢。
P.S:我不想在任何地方使用同步关键字,因为它没有给予线程公平的运行机会(即按线程顺序)
答案 0 :(得分:1)
你想要同步具有相同列表内容的线程是很奇怪的(尽管列表本身是不同的,这使得@RajSharma回答不正确)。然而,这是Java-8 ConcurrentHashMap
:
static ConcurrentHashMap<Collection<String>, Void> map = new ConcurrentHashMap<>();
public static void printListOfStrings(Collection<String> cs) {
map.computeIfAbsent(cs, k -> {
for (String str : cs)
System.out.print(str + " by " + Thread.currentThread().getName());
System.out.println();
return null;
});
}
其余代码是相同的。请注意,map
始终为空,我们从不向其添加元素。但是,当computeIfAbsent
针对单个密钥运行时,此密钥将被阻止用于其他操作,但其他密钥可以同时运行。这里lt1
和lt3
列表相同并且具有相同的哈希码,因此它们的访问权限是同步的。