目录
3.多线程创建方式3:利用Callable接口和Future类来实现:
3.4.1 Callable接口实现类,MyCallable.java:
3.3 运行效果:在创建线程池时,只创建了3个核心线程,当第四次使用时,会复用前3个线程,从而实现有限个线程解决大量问题
1.多线程创建方式:
1.多线程创建方式1,继承Thread类:
2.多线程创建方式2: 匿名内部类写法
package thread;
public class ThreadTest {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程输出" + i);
}
}
};
//还有两种简化写法,我没写
new Thread(runnable).start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程输出" + i);
}
}
}
3.多线程创建方式3:利用Callable接口和Future类来实现:
3.1问题:
3.2步骤:
3.3FutureTask的Api:
3.4实例代码:
3.4.1 Callable接口实现类,MyCallable.java:
package thread;
import java.util.concurrent.Callable;
public class MyCallable implements Callable<String> {
private int n;
public MyCallable(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return "线程求出了1-" + n + "的和是" + sum;
}
}
3.4.2 ThreadTest1:
package thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest1 {
public static void main(String[] args) throws Exception {
//创建一个Callable的对象
Callable<String> call = new MyCallable(100);
//把Callable的对象封装成一个FutureTask对象 (未来任务对象)
// 未来任务对象作用:
//是一个任务对象,实现了Runnable对象
//可以在线程执行完毕后用未来任务对象调用get方法获取线程执行结果
FutureTask<String> f1 = new FutureTask<>(call);
//把任务对象交给Thread对象
new Thread(f1).start();
Callable<String> call2 = new MyCallable(20);
FutureTask<String> f2 = new FutureTask<>(call2);
new Thread(f2).start();
//6、获取线程执行完毕后返回的结果
// 注意,如果执行到这儿,假如上面的线帮还没有执行完毕
// 这里的代码会暂停,等待上面线程执行完毕后才会获取结果。
String s = f1.get();
System.out.println(s);
String s1 = f2.get();
System.out.println(s1);
}
}
3.4.3 运行效果:
2.Thread的常用方法:
3.线程安全问题:
1.存在多个线程在同时执行
2.同时访问一个共享资源
3.存在修改该共享资源
4.线程同步解决线程安全问题
1.同步代码块:
2.同步方法:
3.Lock锁
5.线程通信:生产者消费者问题
6.线程池:
1.线程池的创建1:
package threadsavety;
import java.util.concurrent.*;
public class ThreadCreate {
/*
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
*/
public static void main(String[] args) {
ExecutorService pool = new ThreadPoolExecutor(3, 5,
8, TimeUnit.SECONDS, new ArrayBlockingQueue<>(4),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
}
}
2..线程池处理Runnable
3.线程池处理Callable:
实例代码:
3.1 ThreadCreate.java:
package threadsavety;
import java.util.concurrent.*;
public class ThreadCreate {
/*
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService pool = new ThreadPoolExecutor(3, 5,
8, TimeUnit.SECONDS, new ArrayBlockingQueue<>(4),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
Future<String> submit1 = pool.submit(new MyCallable1(100));
Future<String> submit2 = pool.submit(new MyCallable1(100));
Future<String> submit3 = pool.submit(new MyCallable1(100));
Future<String> submit4 = pool.submit(new MyCallable1(100));
System.out.println(submit1.get());
System.out.println(submit2.get());
System.out.println(submit3.get());
System.out.println(submit4.get());
pool.shutdown();
}
}
3.2 MyCallable1.java:
package threadsavety;
import java.util.concurrent.Callable;
public class MyCallable1 implements Callable<String> {
private int n;
public MyCallable1(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return Thread.currentThread().getName()+"求出了1-" + n + "的和是" + sum;
}
}