一、多线程
1、概述
1.1 理解线程和进程
进程时一个应用程序(软件)
线程是一个进程的执行过程/执行场景
一个进程可以启动多个线程
1.2 java中实现多线程的两种方式
- 创建一个类,直接继承
**java.lang.Thread**重写**run()**方法
- 在run方法中的代码运行在分支线程中
- 创建一个类,实现
**Runnable**接口(常用)
方法
**start ()**//启动线程**setName()**//修改线程名字**getName()**//得到线程名字默认线程名 Thread-0 /1/2
**Thread.currentThread()** 静态方法
//得到当前线程在哪里出现获取得就是拿的线程
Thread t1 = Thread.currentThread();
**Thread.sleep**``(``毫秒``) 静态方法
//让线程睡眠 出现在哪里就是让那个线程睡眠
**interrupt()**
//唤醒睡眠的线程
原理就是直接进去catch语句
合理结束线程
打一个布尔标记
实现线程的第三种方式 实现Callable接口
这种方式可以获取线程的返回值
1.3 代码-java实现多线程方式1 继承 Thread类
public class TreadTest001 {public static void main(String[] args) {A a = new A();a.start(); // 启动线程for (int i = 0; i < 1000; i++){System.out.println("主线程"+i);}}}class A extends Thread{@Overridepublic void run() {for (int i = 0; i < 1000; i++){System.out.println("分支线程"+i);}}}
1.4 代码—-java实现多线程方式2 实现 Runnable 接口
public class ThreadTest01 {public static void main(String[] args) {Thread s = new Thread(new MyThread02());s.start(); //启动线程for (int i = 0; i < 100; i++){System.out.println("主线程"+i);}}}class MyThread02 implements Runnable{@Overridepublic void run() {for (int i = 0; i < 100; i++){System.out.println("分支线程"+i);}}}
1.5线程的五种状态

二、多线程并发/守护线程
1、满足条件
多线程并发
有共享数据
共享数据有修改的行为
2、解决线程安全问题
线程排队执行(不能并发)
尽量使用局部变量代替实例变量/静态变量
如果必须是实例变量,那么可以考虑多new几个对象
以上都不行采用synchronized
这种机制被称为”线程同步机制“
3、synchronized
线程同步机制语法
synchronized(共享对象) {//同步代码块 (和谁同步,填谁和谁的同步对象)}
synchronized出现在实例方法上,锁的是this(不灵活)
public synchronized void doSome(){}
在静态方法上使用synchronized
表示找类锁,类锁永远只有一把
对象锁:一个对象一把锁,一百个对象一百把锁
类锁:100个对象,1把锁
sybchronized 在开发中尽量不要嵌套使用,容易死锁
局部变量不存在线程安全问题
4、守护线程
后台线程 例如:垃圾回收线程
特点:死循环,用户线程结束守护线程自动结束
语法
**setDaemon(true);** // 变成守护线程
**t.setDaemon(true);** //t线程变成守护线程
即使t线程里面是死循环,当主线程结束,守护线程也会结束
三、生产者和消费者
1、概述
wait()和notify()不是线程对象的方法
任何一个java对象都有的方法(Object自带)
wait()和notify()必须建立在synchroniezd基础上
2、wait()
Object o = new Object();
o.wait();
表示让正在o对象上活动的线程进入等待状态(无期限)
直到调用o.notify()方法
会释放锁
3、notify()
o.notify();
唤醒正在等待的线程
不会释放锁
4、死锁
//死锁public class DeadThread {public static void main(String[] args) {Object a = new Object();Object b = new Object();MyThread1 one = new MyThread1(a,b); //线程对象oneMyThread2 two = new MyThread2(a,b); //线程对象twoone.start(); //启动线程onetwo.start(); //启动线程two}}class MyThread1 extends Thread{Object one;Object two;public MyThread1(Object one, Object two) {this.one = one;this.two = two;}@Overridepublic void run() {synchronized(one){try {Thread.sleep(2000); //睡眠2秒} catch (InterruptedException e) {e.printStackTrace();}synchronized (two){}}}}class MyThread2 extends Thread{Object one;Object two;public MyThread2(Object one, Object two) {this.one = one;this.two = two;}@Overridepublic void run() {synchronized(two){try {Thread.sleep(2000); //睡眠两秒} catch (InterruptedException e) {e.printStackTrace();}synchronized (one){}}}}
5、synchronized有三种写法:
第一种:同步代码块 灵活
synchronized(线程共享对象){同步代码块;}
第二种:在实例方法上使用synchronized
表示共享对象一定是this
并且同步代码块是整个方法体
第三种:在静态方法上使用synchronized
表示找类锁。
类锁永远只有1把。
就算创建了100个对象,那类锁也只有一把
对象锁:1个对象1把锁,100个对象100把锁。
类锁:100个对象,也可能只是1把类锁。
