直接贴demo:
1.第一种使用唤醒等待线程方式:
public interface GyCallable<V> {
V call() throws Throwable;
}
public class GyFeature implements Runnable {
private int state;
private Object result;
private GyCallable callable;
private Thread thread;
public GyFeature(GyCallable callable) {
this.callable = callable;
}
@Override
public void run() {
try {
result = callable.call();
state = 2;
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
LockSupport.unpark(thread);
}
}
public Object get() {
while (state == 0) {
thread = Thread.currentThread();
LockSupport.park(thread);
}
return result;
}
}
public class GyTask {
public GyFeature submit(GyCallable callable) {
GyFeature gyFeature = new GyFeature(callable);
Thread t = new Thread(gyFeature);
t.start();
return gyFeature;
}
}
public class Test{
public static void main(String[] args) {
GyTask task = new GyTask();
GyFeature submit = task.submit(() -> {
Thread.sleep(3000);
return "123";
});
GyTask task2 = new GyTask();
GyFeature submit2 = task2.submit(() -> {
Thread.sleep(3000);
return "123";
});
System.out.println(submit.get());
System.out.println(submit2.get());
}
}
2.第二种用到CountDownLatch :
public class Main3 {
@FunctionalInterface
static interface Call<T> {
T call() throws InterruptedException;
}
static class Client<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
static class Service<T> {
private final CountDownLatch c = new CountDownLatch(1);
private final Client<T> client = new Client<>();
Service<T> submit(final Call<T> call) {
new Thread(() -> {
try {
client.setT(call.call());
c.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
return this;
}
public T get() throws InterruptedException {
c.await();
return this.client.getT();
}
}
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
Service<String> submit = new Service<String>().submit(() -> {
Thread.sleep(3000);
return "边做饭边等菜";
});
Thread.sleep(2000);
System.out.println("买菜");
String s = submit.get();
System.out.println(s);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
结果:
买菜
边做饭边等菜
3041
3.第三种使用判断成员变量:
public class Main6 {
@FunctionalInterface
static interface Call<T> {
T call() throws InterruptedException;
}
static class Client<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
static class Service<T> {
private final Client<T> client = new Client<>();
private volatile boolean flag;
Service<T> submit(final Call<T> call) {
new Thread(() -> {
try {
//同步代码块要放在线程里
synchronized (this) {
client.setT(call.call());
flag = true;
this.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
return this;
}
public T get() throws InterruptedException {
synchronized (this) {
if(!flag){
//线程等待释放,让出cpu占用
this.wait();
}
return this.client.getT();
}
}
}
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
Service<String> submit = new Service<String>().submit(() -> {
Thread.sleep(1500);
return "边做饭边等菜";
});
Thread.sleep(500);
System.out.println("买菜");
String s = submit.get();
System.out.println(s);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
其实这个思路就是:
先运行个线程,线程是没有返回值的.这时传入一个封装类,去接受线程里的结果.然后使用线程工具使得到结果方法和异步线程阻塞,改变执行顺序.