我们知道在JAVA的线程中我们只能执行任务,而这个任务不能返回一个值,而Callable的出现就是为了弥补这一缺陷。
Callable:定义一个带有返回值的任务, 并没有真的在执行,需要搭配Thread对象来使用。
Thread本身不提供获取结果的方法,需要凭FurureTask对象来得到结果,这么做是为了解耦合。
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Integer res = 0;
for (int i = 0; i < 10; i++) {
res += i;
}
return res;
}
};
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(futureTask.get());
}//匿名写法
FutureTask<Integer> futureTask = new FutureTask<>(()->{
Integer res = 0;
for (int i = 0; i < 10; i++) {
res += i;
}
return res;
});get方法用于获取FutureTask的返回值,如果FutureTask没有运行完成get方法会产生阻塞,直到线程运行完毕,get拿到返回结果。
通过lock()和unlock()方法加解锁,效率比synchronized低,远古时期用的较多。
如果要使用ReentrantLock进行加锁,可以通过此方式防止忘记解锁
locker.lock();
try {
//代码逻辑
} finally {
locker.unlock();
}ReentrantLock和synchronized的区别:
信号量表示的是“可用资源的个数”,申请一个资源,计数器就会+1,释放一个就会-1,如果为0,继续申请就会陷入阻塞等待。
//设置初始数量
Semaphore semaphore = new Semaphore(5);
//申请一个资源
semaphore.acquire();
//获取多少个资源可以申请
System.out.println(semaphore.availablePermits());
//释放一个资源
semaphore.release();
System.out.println(semaphore.availablePermits());作用:
特殊场景: 当初始值为1时,等价于“锁”。
Semaphore mutex = new Semaphore(1); // 二进制信号量
void criticalSection() throws InterruptedException {
mutex.acquire();
try {
// 临界区代码(同一时间仅一个线程可进入)
} finally {
mutex.release();
}
}在使用多线程,经常把一个大任务拆分成多个子任务,可以提高程序的效率。
那么我们如何判定这个大任务已经完成了呢?Java引入了CountDownLatch类帮助我们判定。
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(10);
//重写工厂类方法
ThreadFactory threadFactory = new ThreadFactory() {
private int cnt = 0;
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "Thread" + cnt);
thread.setDaemon(true);
return thread;
}
};
//使用工厂类创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
//提交任务
for (int i = 0; i < 10; i++) {
int id = i;
executorService.submit(()->{
System.out.println("开始" + Thread.currentThread().getName() + id);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("结束" + Thread.currentThread().getName() + id);
countDownLatch.countDown();
});
}
//等待全部完成
countDownLatch.await();
System.out.println("全部结束了");
}感谢各位的观看Thanks♪(・ω・)ノ,如果觉得满意的话留个关注再走吧。