在 call() 方法的 return 语句执行之前具有对象引用的未来对象
Future Object having Object reference before return statement of call() method executes
以下是我的程序和输出。
甚至在执行 call() 方法的 return 语句之前(第 1 行)for each 循环(第 2 行) 打印非空的 Future 变量 f 的引用。
我的问题是,在执行 return 语句并将对象分配给 f 之前,future 变量怎么可能指向某些对象而不是 null,这在内部是如何工作的。
代码:-
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ObjectPool2
{
public static void main(String[] args)
{
Pool[] pObject = {new Pool(),new Pool(),new Pool(),new Pool(),new Pool(),new Pool(),new Pool(),new Pool()};
ExecutorService es = Executors.newFixedThreadPool(8);
Future f = null;
for(Pool p : pObject) **// line 2**
{
f = es.submit(p);
System.out.println(f.toString());
System.out.println(f);
System.out.println(f);
System.out.println(f);
System.out.println("---------------");
}
System.out.println(f);
}
}
class Pool implements Callable
{
public static ConcurrentLinkedQueue unlocked_queue2 = new ConcurrentLinkedQueue();
public static ConcurrentLinkedQueue locked_queue2 = new ConcurrentLinkedQueue();
static
{
int i = 1;
int i2 = 2;
int i3 = 3;
int i4 = 4;
unlocked_queue2.add(i);
unlocked_queue2.add(i2);
unlocked_queue2.add(i3);
unlocked_queue2.add(i4);
}
public Object get() throws InterruptedException
{
synchronized(getClass())
{
while(unlocked_queue2.isEmpty())
{
System.out.println(Thread.currentThread().getName() + " waiting ");
this.getClass().wait();
}
int op = (int)unlocked_queue2.poll();
locked_queue2.add(op);
System.out.println(Thread.currentThread().getName() + " got lock of : "+ op +" now going to sleep");
Thread.currentThread().sleep(5000);
return op;
}
}
public void leave()
{
synchronized(getClass())
{
int ol = (int)locked_queue2.poll();
unlocked_queue2.add(ol);
System.out.println(Thread.currentThread().getName() + " leaving lock of : "+ ol);
this.getClass().notifyAll();
}
}
@Override
public Object call() throws Exception
{
Object lock = get();
return lock; **//line 1**
}
}
输出:-
java.util.concurrent.FutureTask@55f96302
java.util.concurrent.FutureTask@55f96302
java.util.concurrent.FutureTask@55f96302
java.util.concurrent.FutureTask@55f96302
---------------
pool-1-thread-1 got lock of : 1 now going to sleep
java.util.concurrent.FutureTask@42a57993
java.util.concurrent.FutureTask@42a57993
java.util.concurrent.FutureTask@42a57993
java.util.concurrent.FutureTask@42a57993
---------------
java.util.concurrent.FutureTask@6bc7c054
java.util.concurrent.FutureTask@6bc7c054
java.util.concurrent.FutureTask@6bc7c054
java.util.concurrent.FutureTask@6bc7c054
---------------
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@4aa298b7
---------------
java.util.concurrent.FutureTask@28d93b30
java.util.concurrent.FutureTask@28d93b30
java.util.concurrent.FutureTask@28d93b30
java.util.concurrent.FutureTask@28d93b30
---------------
java.util.concurrent.FutureTask@4554617c
java.util.concurrent.FutureTask@4554617c
java.util.concurrent.FutureTask@4554617c
java.util.concurrent.FutureTask@4554617c
---------------
java.util.concurrent.FutureTask@1540e19d
java.util.concurrent.FutureTask@1540e19d
java.util.concurrent.FutureTask@1540e19d
java.util.concurrent.FutureTask@1540e19d
---------------
java.util.concurrent.FutureTask@14ae5a5
java.util.concurrent.FutureTask@14ae5a5
java.util.concurrent.FutureTask@14ae5a5
java.util.concurrent.FutureTask@14ae5a5
---------------
java.util.concurrent.FutureTask@14ae5a5
pool-1-thread-8 got lock of : 2 now going to sleep
pool-1-thread-7 got lock of : 3 now going to sleep
pool-1-thread-6 got lock of : 4 now going to sleep
pool-1-thread-5 waiting
pool-1-thread-4 waiting
pool-1-thread-3 waiting
pool-1-thread-2 waiting
Future
的创建是同步的,在主调用线程中实现。
当您将 Callable
提交给 ThreadPoolExecutor
时,它的工作方式如下:
public Future submit(Callable callable) {
Future future = new FutureTask(callable);
if (currentThread < coreThread) {
createNewThreadWhichWillExecuteTheFutureAutomically(); // this will not get blocked, the thread will execute the future itself
} else if (queueIsNotFull) {
putTheFutureInQueue(future);
} else if (currentThread < maxThread) {
createNewThreadWhichWillExecuteTheFutureAutomically(); // this will not get blocked, the thread will execute the future itself
} else {
throw RejectedExecutionException();
}
return future;
}
而future.get()
的执行不会return直到任务执行完或者中断或超时。
实际上这是你给f赋值的地方
f = es.submit(p);
之后 f
行不再是空行。它是一个未来类型的对象。你可以从系统中看到 - 它打印出来
java.util.concurrent.FutureTask@135fbaa4 基本上是 FutureTask 类型的对象。
当您的线程完成时,它不会更改 f 的值 -> 它仍然是 future 类型的对象,但它已完成执行(基本上 isDone() 变为 true)。完成后,您可以从以下位置获得实际结果:
f.get();
您可以检查它是否已经完成:
f.isDone()
以下是我的程序和输出。
甚至在执行 call() 方法的 return 语句之前(第 1 行)for each 循环(第 2 行) 打印非空的 Future 变量 f 的引用。
我的问题是,在执行 return 语句并将对象分配给 f 之前,future 变量怎么可能指向某些对象而不是 null,这在内部是如何工作的。
代码:-
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ObjectPool2
{
public static void main(String[] args)
{
Pool[] pObject = {new Pool(),new Pool(),new Pool(),new Pool(),new Pool(),new Pool(),new Pool(),new Pool()};
ExecutorService es = Executors.newFixedThreadPool(8);
Future f = null;
for(Pool p : pObject) **// line 2**
{
f = es.submit(p);
System.out.println(f.toString());
System.out.println(f);
System.out.println(f);
System.out.println(f);
System.out.println("---------------");
}
System.out.println(f);
}
}
class Pool implements Callable
{
public static ConcurrentLinkedQueue unlocked_queue2 = new ConcurrentLinkedQueue();
public static ConcurrentLinkedQueue locked_queue2 = new ConcurrentLinkedQueue();
static
{
int i = 1;
int i2 = 2;
int i3 = 3;
int i4 = 4;
unlocked_queue2.add(i);
unlocked_queue2.add(i2);
unlocked_queue2.add(i3);
unlocked_queue2.add(i4);
}
public Object get() throws InterruptedException
{
synchronized(getClass())
{
while(unlocked_queue2.isEmpty())
{
System.out.println(Thread.currentThread().getName() + " waiting ");
this.getClass().wait();
}
int op = (int)unlocked_queue2.poll();
locked_queue2.add(op);
System.out.println(Thread.currentThread().getName() + " got lock of : "+ op +" now going to sleep");
Thread.currentThread().sleep(5000);
return op;
}
}
public void leave()
{
synchronized(getClass())
{
int ol = (int)locked_queue2.poll();
unlocked_queue2.add(ol);
System.out.println(Thread.currentThread().getName() + " leaving lock of : "+ ol);
this.getClass().notifyAll();
}
}
@Override
public Object call() throws Exception
{
Object lock = get();
return lock; **//line 1**
}
}
输出:-
java.util.concurrent.FutureTask@55f96302
java.util.concurrent.FutureTask@55f96302
java.util.concurrent.FutureTask@55f96302
java.util.concurrent.FutureTask@55f96302
---------------
pool-1-thread-1 got lock of : 1 now going to sleep
java.util.concurrent.FutureTask@42a57993
java.util.concurrent.FutureTask@42a57993
java.util.concurrent.FutureTask@42a57993
java.util.concurrent.FutureTask@42a57993
---------------
java.util.concurrent.FutureTask@6bc7c054
java.util.concurrent.FutureTask@6bc7c054
java.util.concurrent.FutureTask@6bc7c054
java.util.concurrent.FutureTask@6bc7c054
---------------
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@4aa298b7
---------------
java.util.concurrent.FutureTask@28d93b30
java.util.concurrent.FutureTask@28d93b30
java.util.concurrent.FutureTask@28d93b30
java.util.concurrent.FutureTask@28d93b30
---------------
java.util.concurrent.FutureTask@4554617c
java.util.concurrent.FutureTask@4554617c
java.util.concurrent.FutureTask@4554617c
java.util.concurrent.FutureTask@4554617c
---------------
java.util.concurrent.FutureTask@1540e19d
java.util.concurrent.FutureTask@1540e19d
java.util.concurrent.FutureTask@1540e19d
java.util.concurrent.FutureTask@1540e19d
---------------
java.util.concurrent.FutureTask@14ae5a5
java.util.concurrent.FutureTask@14ae5a5
java.util.concurrent.FutureTask@14ae5a5
java.util.concurrent.FutureTask@14ae5a5
---------------
java.util.concurrent.FutureTask@14ae5a5
pool-1-thread-8 got lock of : 2 now going to sleep
pool-1-thread-7 got lock of : 3 now going to sleep
pool-1-thread-6 got lock of : 4 now going to sleep
pool-1-thread-5 waiting
pool-1-thread-4 waiting
pool-1-thread-3 waiting
pool-1-thread-2 waiting
Future
的创建是同步的,在主调用线程中实现。
当您将 Callable
提交给 ThreadPoolExecutor
时,它的工作方式如下:
public Future submit(Callable callable) {
Future future = new FutureTask(callable);
if (currentThread < coreThread) {
createNewThreadWhichWillExecuteTheFutureAutomically(); // this will not get blocked, the thread will execute the future itself
} else if (queueIsNotFull) {
putTheFutureInQueue(future);
} else if (currentThread < maxThread) {
createNewThreadWhichWillExecuteTheFutureAutomically(); // this will not get blocked, the thread will execute the future itself
} else {
throw RejectedExecutionException();
}
return future;
}
而future.get()
的执行不会return直到任务执行完或者中断或超时。
实际上这是你给f赋值的地方
f = es.submit(p);
之后 f
行不再是空行。它是一个未来类型的对象。你可以从系统中看到 - 它打印出来
java.util.concurrent.FutureTask@135fbaa4 基本上是 FutureTask 类型的对象。
当您的线程完成时,它不会更改 f 的值 -> 它仍然是 future 类型的对象,但它已完成执行(基本上 isDone() 变为 true)。完成后,您可以从以下位置获得实际结果:
f.get();
您可以检查它是否已经完成:
f.isDone()