多线程之二
作者:互联网
线程通信
/**
* 两个线程交替打印1-100之间的数字
*/
public class ThreadTest3 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
Thread t1 = new Thread(demo04);
Thread t2 = new Thread(demo04);
t1.setName("线程一");
t2.setName("线程二");
t1.start();
t2.start();
}
}
class Demo04 implements Runnable{
private static int i=1;
@Override
public void run() {
while (true){
synchronized (this){
//唤醒所有线程,首次执行时无效果
notifyAll();
if (i<=100){
System.out.println(Thread.currentThread().getName()+":"+i);
i++;
try {
//使当前线程沉睡。可以被notifyAll()和notify()唤醒
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}
}
}
}
}
wait() 与 notify() 和 notifyAll()
- wait():令当前线程挂起并放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当 前线程排队等候其他线程调用notify()或notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有 权后才能继续执行。
- notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
- notifyAll ():唤醒正在排队等待资源的所有线程结束等待.
这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报
java.lang.IllegalMonitorStateException异常。
面试题:sleep() 和 wait()的异同?
- 相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
- 不同点:
- 两个方法声明的位置不同:Thread类中声明sleep() , Object类中声明wait()
- 调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
- 关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。
JDK5.0新增的线程创建方式
实现Callable接口
-
Callable接口
-
相比run()方法,可以有返回值
-
方法可以抛出异常
-
支持泛型的返回值
-
需要借助FutureTask类,比如获取返回结果
-
-
Future接口
- 可以对具体Runnable、Callable任务的执行结果进行取消、查询是 否完成、获取结果等。
- FutrueTask是Futrue接口的唯一的实现类
- FutureTask 同时实现了Runnable, Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
public class ThreadTest4 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Demo05 demo05 = new Demo05();
FutureTask futureTask = new FutureTask(demo05);
new Thread(futureTask).start();
Object o = futureTask.get();
System.out.println(o);
}
}
class Demo05 implements Callable{
@Override
public Object call() throws Exception {
int sum =0;
for (int i = 1; i <=100 ; i++) {
if (i%2==0){
System.out.println(i);
sum+=i;
}
}
return sum;
}
}
线程池
- 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程, 对性能影响很大。
- 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完 放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交 通工具。
好处:
- 提高响应速度(减少了创建新线程的时间)
- 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
- 便于线程管理
- corePoolSize:核心池的大小
- maximumPoolSize:最大线程数
- keepAliveTime:线程没有任务时最多保持多长时间后会终止
- …
实现
- JDK 5.0起提供了线程池相关API:ExecutorService 和 Executors
- ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
- Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
public class Pool {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new Demo06());
service.shutdown();
}
}
class Demo06 implements Runnable{
@Override
public void run() {
for (int i = 1; i <=100 ; i++) {
if (i%2==0){
System.out.println(i);
}
}
}
}
标签:Thread,class,之二,线程,new,多线程,public,wait 来源: https://www.cnblogs.com/Boerk/p/16094993.html