漂亮的手机网站模板,WordPress万级数据优化,郑州惠济区建设局网站,网站ppt缩略图文章目录 1. 线程创建方式1.1 继承Thread1.2 声明一个实现Runnable接口的类1.3 利用Callable接口、FutureTask类来实现 2. 线程同步2.1 同步代码块2.2 同步方法2.3 Lock锁 3. 线程同步4. 线程池 1. 线程创建方式
1.1 继承Thread
定义子类#xff0c;继承Thread#xff0c;创… 文章目录 1. 线程创建方式1.1 继承Thread1.2 声明一个实现Runnable接口的类1.3 利用Callable接口、FutureTask类来实现 2. 线程同步2.1 同步代码块2.2 同步方法2.3 Lock锁 3. 线程同步4. 线程池 1. 线程创建方式
1.1 继承Thread
定义子类继承Thread创建对象并调用start启动线程
优点编码简单缺点线程类已经继承Thread无法继承其他类不利于功能的扩展
public class Main {// main方法是有一条默认的主线程执行的public static void main(String[] args) {// 1. 创建线程类的对象代表一个线程Thread t new MyThread();// 2. 启动线程t.start();for (int i 0; i 10000; i) {System.out.println(主线程输出 i);}}
}注意是调用Thread的start方法而不是run方法!!! public class MyThread extends Thread{Overridepublic void run() {for (int i 0; i 10000; i) {System.out.println(子线程输出 i);}super.run();}
}1.2 声明一个实现Runnable接口的类
优点只是实现了一个接口还可以继承一个类实现其他接口扩展性强缺点需要多创建一个Runnable对象
class MyRunnable implements Runnable {Overridepublic void run() {for (int i 0; i 10000; i) {System.out.println(子线程输出 i);}}
}
static void test_Runnable() {
// Runnable target new MyRunnable(); // 任务对象不是线程对象
// new Thread(target).start();// lambdanew Thread(() - {for (int i 0; i 10000; i) {System.out.println(子线程输出 i);}for (int i 0; i 10; i) {System.out.println(主线程输出 i);}}1.3 利用Callable接口、FutureTask类来实现
优点可以返回线程执行完后的结果缺点编码复杂
class MyCallable implements CallableString {int n;public MyCallable(int n) {this.n n;}Overridepublic String call() throws Exception {// 描述线程的任务返回线程执行后的结果// 求1-n的和int sum 0;for(int i 1; i n; i)sum n;return 1~n的总和是 sum;}
}static void test_Callble() {// 1. 创建Callable对象MyCallable call new MyCallable(50);// 2. 把Callable对象封装成FutureTask对象// 1. 是一个任务对象实现了Runnable对象// 2. 可以在线程执行完后调用get方法获取FutureTaskString f1 new FutureTask(call);new Thread(f1).start();for (int i 0; i 10; i) {System.out.println(主线程输出 i);}// 获取线程执行完毕后的结果String s null;try {// 会等到线程执行完毕这行代码再执行s f1.get();} catch (Exception e) {e.printStackTrace();}System.out.println(s);}我发现啊Java的多线程和C的多线程不一样的点是Java中创建子线程如果主线程先执行完了子线程没有执行完子线程会继续执行但是C会被终止。
不过join方法都有着相同的用处那就是阻塞主线程等待线程执行完毕后再执行主线程后面的代码。
2. 线程同步
2.1 同步代码块
synchronized(同步锁) {访问共享资源的核心代码
}这个同步锁是一个字符串也可以双引号在内存中存在常量区只有一份只要是一个唯一对象即可 。 但最好是用共享资源作为锁比如说this。
如果要调用静态方法同步锁采用类名.class锁住整个class。
2.2 同步方法
把访问共享资源的核心方法上锁保证线程安全。这样能保证一个对象中只有一个方法在执行其他方法都无法执行。
修饰符 synchronized 返回值类型 方法名形参列表{操作共享资源得到代码
}2.3 Lock锁
Lock是一个接口类可以用实现类ReentrantLock来实例化一个锁来使用。
Lock lk new ReentrantLock();
lk.lock();
lk.unlock();3. 线程同步
来了来了条件遍历来了。注意一定要和锁搭配使用。 来一个经典的例子吧2个线程交替打印A和B
package TestDemo;// 2个线程交替打印A和B10次
public class Test2 {public static int count;static final Object lock new Object(); // 锁public static void main(String[] args){Thread t1 new Thread(() - {for (int i 0; i 10; i) {synchronized (lock) {System.out.println(Thread.currentThread().getName() 打印A);lock.notify();try {if(i 9)lock.wait();} catch (Exception e) {e.printStackTrace();}}}}, A线程);Thread t2 new Thread(() - {for (int i 0; i 10; i) {synchronized (lock) {System.out.println(Thread.currentThread().getName() 打印B);lock.notify();try {if(i 9)lock.wait();} catch (Exception e) {e.printStackTrace();}}}}, B线程);t1.start();t2.start();}
}
4. 线程池
JDK5提供了代表线程池的接口ExecutorService。比较常用的实现类是ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueRunnable workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) corePoolSize指定线程池的核心线程数量maximumPoolSize指定线程池的最大线程数量keepAliveTime指定临时线程的存活时间unit指定临时线程存货的时间单位workQueue指定线程池的任务队列threadFactory指定线程池的任务工厂handler指定线程池的拒绝策略任务队列满了后新任务来了怎么处理
线程池默认是不会死亡的除非调用shutdown()或者shutdownNow()。
临时线程什么时候创建 新任务提交时发现核心线程都在忙任务队列也满了并且还可以创建临时线程此时才会创建临时线程去执行新任务而不是任务队列的任务插队。什么时候会开始拒绝新任务 核心线程和临时线程都在忙任务队列也满了新的任务过来的时候才会开始拒绝任务。
Executors 是线程池的一个工具类提供了很多静态方法用于返回不同特点的线程池对象。