理解Java中的多线程
我正在学习Java中的理解Java中的多线程,java,multithreading,concurrency,Java,Multithreading,Concurrency,我正在学习Java中的多线程。问题陈述是:假设有一个datastruture可以包含数百万个整数,现在我想在其中搜索一个键。我想使用2个线程,这样如果其中任何一个线程找到了密钥,它应该将一个共享布尔变量设置为false,并且两个线程都应该停止进一步的处理 以下是我正在尝试的: public class Test implements Runnable{ private List<Integer> list; private Boolean value; pr
多线程
。问题陈述是:假设有一个datastruture可以包含数百万个整数,现在我想在其中搜索一个键。我想使用2个线程,这样如果其中任何一个线程找到了密钥,它应该将一个共享布尔变量设置为false,并且两个线程都应该停止进一步的处理
以下是我正在尝试的:
public class Test implements Runnable{
private List<Integer> list;
private Boolean value;
private int key = 27;
public Test(List<Integer> list,boolean value) {
this.list=list;
this.value=value;
}
@Override
public void run() {
synchronized (value) {
if(value){
Thread.currentThread().interrupt();
}
for(int i=0;i<list.size();i++){
if(list.get(i)==key){
System.out.println("Found by: "+Thread.currentThread().getName());
value = true;
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() +": "+ list.get(i));
}
}
}
}
公共类测试实现可运行{
私人名单;
私有布尔值;
私钥=27;
公共测试(列表,布尔值){
this.list=list;
这个。值=值;
}
@凌驾
公开募捐{
已同步(值){
如果(值){
Thread.currentThread().interrupt();
}
对于(int i=0;i,通过将线程的主逻辑包装在一个同步块中,该块中代码的执行变得相互排斥。线程1将进入该块,获取“value”上的锁,并在返回锁并允许线程2运行之前运行整个循环
如果只包装标志“value”的检查和设置,那么两个线程应该同时运行代码
编辑:正如其他人所讨论的,在测试类中使“value”成为一个静态volatile boolean
,而根本不使用同步块,也会起作用。这是因为访问volatile变量就像在同步块中一样
参考:您正在将整个代码块包装在对象值下的同步块下。这意味着,一旦执行到达同步块,第一个线程将保持监视器到对象值,并且任何后续线程都将阻塞,直到监视器is已发布
请注意整个块如何:
synchronized (value){
if(value){
Thread.currentThread().interrupt();
}
for(int i=0; i < list.size(); i++){
if(list.get(i) == key){
System.out.println("Found by: "+Thread.currentThread().getName());
value = true;
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() +": "+ list.get(i));
}
}
此外,您现在尝试执行的任务是构建Fork/Join池的目的。我建议您在Oracle的java教程中了解如何在分而治之的方法中使用Fork/Join池。将布尔值设为静态,以便两个线程都可以访问和编辑同一个变量。这样,您就不需要传入它。然后作为一旦一个线程将其更改为true,第二个线程也将停止,因为它使用的是相同的值。您不应该在found
标志上获得锁-这只会确保只有一个线程可以运行。相反,请确保该标志static
以便共享,而volatile
则无法缓存
此外,您应该更频繁地检查标志
private List<Integer> list;
private int key = 27;
private static volatile boolean found;
public Test(List<Integer> list, boolean value) {
this.list = list;
this.found = value;
}
@Override
public void run() {
for (int i = 0; i < list.size(); i++) {
// Has the other thread found it?
if (found) {
Thread.currentThread().interrupt();
}
if (list.get(i) == key) {
System.out.println("Found by: " + Thread.currentThread().getName());
// I found it!
found = true;
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + ": " + list.get(i));
}
}
私有列表;
私钥=27;
发现私有静态易失布尔值;
公共测试(列表,布尔值){
this.list=列表;
this.found=值;
}
@凌驾
公开募捐{
对于(int i=0;i
顺便说一句:你的两个线程都从0
开始,并在数组中遍历-我假设你在这段代码中这样做是为了演示,你要么让它们从另一端工作,要么随机遍历。为什么要使用synchronized
?“共享布尔变量”建议您可能想在相关的地方使用静态
关键字…@MuratK。因为布尔
是共享资源?这不是正确的方法吗???@JonK在这里不原子布尔
工作吗?也许静态易失性布尔
可以工作。我想使用易失性布尔
,我必须使线程并发运行。但是,我将如何共享它?访问/修改volatile变量就像它被同步块包围一样。您有两个选项:1.继续使用同步的块,但仅在修改或访问值的位置周围使用。2.将值设为测试的volatile static
成员并删除同步块两个线程都在运行,直到完成执行。它们没有中断,循环正在完成如果(Thread.currentThread().isInterrupted()){System.out.println(“线程中断\n退出…”);break;}为什么我需要添加这些?为什么调用interrupt
方法时没有停止执行?@VivekVardhan-既然run
不能抛出中断,您必须自己检查中断。查看interrupt()
的文档,它所做的只是设置一个标志。
private static volatile Boolean value;
private List<Integer> list;
private int key = 27;
private static volatile boolean found;
public Test(List<Integer> list, boolean value) {
this.list = list;
this.found = value;
}
@Override
public void run() {
for (int i = 0; i < list.size(); i++) {
// Has the other thread found it?
if (found) {
Thread.currentThread().interrupt();
}
if (list.get(i) == key) {
System.out.println("Found by: " + Thread.currentThread().getName());
// I found it!
found = true;
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + ": " + list.get(i));
}
}