简介
每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的Thread
对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。
多线程创建
继承Thread类(重点)
线程开启不一定立即执行,cpu安排调度
public class TestThread extends Thread {
@Override
public void run() {
for (int i=0;i<20;i++){
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args) {
//创建一个线程对象
TestThread testThread = new TestThread();
//调用start方法开启线程,不调用run方法
testThread.start();
for (int i=0;i<2000;i++){
System.out.println("我在看多线程"+i);
}
}
}
实现Runnable接口(重点)
public class TestThread2 implements Runnable {
@Override
public void run() {
for (int i=0;i<20;i++){
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args) {
//创建Runnable接口的实现类对象
TestThread2 testThread2 = new TestThread2();
//创建线程对象,通过线程对象来开启线程
Thread thread = new Thread(testThread2);
//调用start方法开启线程
thread.start();
for (int i=0;i<2000;i++){
System.out.println("我在看多线程"+i);
}
}
}
实现callable接口(了解)
静态代理模式
-
真实对象和代理对象都要实现同一个接口
-
代理对象要代理真实对象
-
代理对象可以做很多真实对象做不了的事情
-
真实对象可以专注做自己的事情
public class TestThread3 { public static void main(String[] args) { weddingCompany weddingCompany = new weddingCompany(new You()); weddingCompany.happyMarry(); } } //接口 interface Marry{ void happyMarry(); } //真实角色,要结婚的人 class You implements Marry{ @Override public void happyMarry() { System.out.println("真实角色要结婚了。"); } } //代理角色,婚庆公司 class weddingCompany implements Marry{ private Marry target; public weddingCompany(Marry target) { this.target = target; } @Override public void happyMarry() { before(); this.target.happyMarry(); after(); } private void before(){ System.out.println("结婚前,做准备"); } private void after(){ System.out.println("结婚后,收尾款"); } }
Lambda表达式
为什么使用lambda表达式
- 避免匿名内部类定义过多
- 让代码看起来更加简洁
- 去掉了一堆没有意义的代码,只留下了核心的逻辑
函数式接口
-
任何接口,如果只包含唯一一个抽象方法,那么他就是一个函数式接口
public interface Runnable{ public abstract void run(); }
-
对于函数式接口,可以通过lambda表达式来创建该接口的对象
/**
* lambda表达式的推导
*/
public class LambdaTest {
//3.静态内部类
static class Ilike2 implements Like{
@Override
public void lambda() {
System.out.println("i like lambda 2!");
}
}
public static void main(String[] args) {
//4.局部内部类
class Ilike3 implements Like{
@Override
public void lambda() {
System.out.println("i like lambda 3!");
}
}
//外部类对象
Like like = new Ilike1();
like.lambda();
//静态内部类对象
like = new Ilike2();
like.lambda();
//局部内部类对象
like = new Ilike3();
like.lambda();
//5.匿名内部类,没有类的名称,必须借助接口或者父类
like = new Like() {
@Override
public void lambda() {
System.out.println("i like lambda 4!");
}
};
//匿名内部类调用方法
like.lambda();
//6.用lambda简化
like = ()->{
System.out.println("i like lambda 5!");
};
like.lambda();
}
}
//1.定义一个接口
interface Like{
void lambda();
}
//2.外部类
class Ilike1 implements Like{
@Override
public void lambda() {
System.out.println("i like lambda 1!");
}
}
线程
线程停止
- 建议线程正常停止—>利用循环次数,不建议死循环
- 建议使用标志位—>设置一个停止标志位
- 不建议使用stop、destroy等JDK不在建议使用的过时方法
public class StopThread implements Runnable{
private boolean flag=true;
@Override
public void run() {
int i=0;
while (flag){
System.out.println("run.....Thread"+(++i));
}
}
//设置一个公开的方法停止线程,即转换标志位
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
StopThread testThread = new StopThread();
new Thread(testThread).start();
for (int i=0;i<=10000;i++){
System.out.println("main"+i);
if (i==4000){
testThread.stop();
System.out.println("线程停止了!!!!!!!!!!!!!");
}
}
}
}
线程休眠
- sleep(时间)指当前线程阻塞的时间(毫秒)
- sleep使用时存在异常,需要处理
- sleep时间到达后线程进入就绪状态
- sleep可以模拟网络延时、倒计时等
- 每一个对象都有一个锁,sleep不会释放锁
线程礼让(yield方法)
- 礼让线程,让当前正在执行的线程暂停,但不阻塞
- 将线程从运行状态转为就绪状态
- 让cpu重新调度,礼让不一定成功,看cpu
线程强制执行 join
线程优先级
守护线程
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
并发与线程同步
synchronized关键字
同步方法与同步块
Lock锁
- Lock是显示锁(需要手动开启和手动关闭),synchronized是隐式锁,出了作用域以后会自动释放
- Lock只有代码块锁,synchronized有代码块锁和方法锁
- 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好,有很好的扩展性
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
(new Thread(testLock2)).start();
(new Thread(testLock2)).start();
(new Thread(testLock2)).start();
}
}
class TestLock2 implements Runnable{
private final ReentrantLock reentrantLock = new ReentrantLock();
private int ticketNum = 100;
@Override
public void run() {
while (true){
try {
//开启锁
reentrantLock.lock();
if (ticketNum>0){
/*try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
System.out.println(ticketNum--);
}else{
break;
}
}finally {
//关闭锁
reentrantLock.unlock();
}
}
}
}
线程池
//创建服务,创建线程池,参数10为线程池的大小
ExecutorService service = Executors.newFixedThreadPool(10);
//执行
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//关闭连接
service.shutdown();