JavaSE多线程总结
1.进程与线程的定义
进程:一个应用程序。 线程:一个应用程序的执行场景或是执行单元
举例: 进程1:阿里巴巴 线程A: 马老师 线程B: 前台小姐姐
进程2:京东 线程A: 刘老师 线程B: 前台小姐姐
进程1和进程2是独立不共享的 线程1和线程2堆内存和方法区共享;栈空间独立不共享
2.实现线程的方法
编写一个类,直接继承Thread,重写run方法:
class MyThread extends Thread{
@Override
public void run(){}
}
MyThread m
= new MyThread;
m
.start();
`编写一个类,实现Runnable接口,重写run方法:
class MyThread implements Runnable{
@Override
public void run(){}
}
Thread t
= new MyThread(new Runnable);
t
.start();
采用匿名内部类:
Thread t
= new Thread(new Runnable(){
@Override
public void run(){}
});
t
.start();
3.线程的生命周期
注意:锁池不算生命周期中的状态。线程生命周期五大状态:开始,就绪状态,运行状态,阻塞状态,结束。
4.获取线程的名字
currentThread()方法:
public static void main(String args
[]){
Thread currentThread
= Thread
.currentThread();
System
.out
.println(currentThread
.getName());
MyThread2 m2
= new MyThread2();
m2
.setName("T1");
String s
= m2
.getName();
System
.out
.println(s
);
}
class MyThread2 extends Thread{
@Override
public void run(){
for(int i
=0; i
<100; i
++){
Thread currentThread
= Thread
.currentThread();
System
.out
.println(currentThread
.getName()+" "+i
);
}
}
}
5.线程安全
未来的开发中,我们的项目是运行在服务器上的,服务器已经将线程定义并穿创建了,我们需要做的就是确保我们的代码 数据是否是安全的?
5.1 线程安全问题出现的条件:
①多线程并发 ②有共享资源 ③共享资源有修改的行为
5.2如何解决线程安全问题:
存在线程安全问题时:需要执行线程排队处理(多个线程不能并发),也称之为 “线程同步机制”。
5.3同步/异步机制:
异步编程模型:线程A和线程B,各自执行各自的,A不管B,B不管A,谁也不需要谁(多个线程并发,效率高,安全低)
同步编程模型:线程A和线程B,当线程A执行时,线程B必须排队等候线程A执行完毕后再进行操作;(多个线程排队执行,效率低,安全高)
5.4synchronized三种写法:
①同步代码块
synchronized (线程共享对象){
同步代码块;
}
②在实例方法上使用synchronized
表示共享对象一定this
并且同步代码块是整个方法体
③在静态方法上使用synchronized
表示找类锁
类锁永远只有一把
就算创建了100个对象,类锁也只有一把
5.5实际开发中如何解决线程安全问题:
synchronized会让程序的执行效率降低,用户体验极差
①尽量使用局部变量代替 “实例变量和静态变量”
②如果必须是实例变量,那么可以考虑创建多个对象,这样实例变量的内存就不共享了(1个线程对应1个对象,100个线程对应100个对象,
对象不共享,就没有数据安全问题了)
③如果不能使用局部变量,对象也不能创建多个,这个时候就只能选择synchronized,线程同步机制
5.6线程其他内容:
①守护线程 .setDaemon()
java中线程分为两大类: 一种是用户线程:main属于用户线程 一种是守护线程(后台线程):垃圾回收机制 守护线程的特点: 一般守护线程是死循环,所有的用户线程只要结束,守护线程就会自动结束
②定时器
③ 实现线程的第三种方式 Future方式,实现Callable接口(JDK8新特性) 这种方式可以获得返回值
④关于Object的wait和notify方法(生产者消费者模式) wait方法和notify方法不是线程对象的方法,是java中任何一个java对象都有的方法 wait方法作用: Object o = new Object; o.wait(); 让正在o对象上活动的线程进入等待状态,无期限等待,知道被唤醒,o.wait()会让 “当前线程”进入等待状态 o.notify()唤醒正在o对象等待的线程 o.notifyALL()唤醒正在o对象等待的所有线程
5.7生产者/消费者模式
public class TestThread10 {
public static void main(String
[] args
) {
List list
= new ArrayList();
Thread t1
= new Thread(new Producer(list
));
Thread t2
= new Thread(new Consumer(list
));
t1
.setName("生产者线程");
t2
.setName("消费者线程");
t1
.start();
t2
.start();
}
}
class Producer implements Runnable{
private List list
;
public Producer(List list
){
this.list
= list
;
}
@Override
public void run() {
while (true){
synchronized (list
) {
if (list
.size() > 0) {
try {
list
.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
Object obj
= new Object();
list
.add(obj
);
System
.out
.println(Thread
.currentThread().getName()+"-->"+obj
);
list
.notify();
}
}
}
}
class Consumer implements Runnable{
private List list
;
public Consumer(List list
){
this.list
= list
;
}
@Override
public void run() {
while (true){
synchronized (list
) {
if (list
.size() == 0) {
try {
list
.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
Object obj
= list
.remove(0);
System
.out
.println(Thread
.currentThread().getName()+"-->"+obj
);
list
.notify();
}
}
}
}
多线程这一块总结了这么多,把学到的知识梳理了一下,可能还有些没有总结到,希望这些对大家有帮助。另外生产者消费者这一块,我也是看了好久,也希望各位大佬能给出自己的理解供参考~!