Java-线程-2
创建线程的另一种方法:
Runnable接口
线程安全
Runnable
创建线程的另一种方法:使用Runnable接口
开启线程的两个构造
1 | Thread(Runnable target) |
示例代码:
实现类
1 | //创建Runnable接口的实现类 |
main函数
1 | public class demo { |
两种方法的区别
区别:
实现Runnable接口创建多线程的好处:
- 避免了单继承的局限性( 以接很多个)
- 增强了程序的扩展性,降低了程序的耦合性(解耦)
- 实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离
- 实现类重写run方法实现设置线程任务
- 创建Thread对象,调用start方法,来开启新的线程
- 实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离
多线程安全
在多线程访问共享数据时,容易发生错误
解决安全问题:同步技术——有三个
同步代码块
锁对象:任意的对象,但是必须保证多个线程使用的锁对象是同一个
作用:把同步代码块锁住,只让一个线程在同步代码块中执行
1 | synchronized ("同步锁"){ |
示例
1 | public class runnable implements Runnable { |
同步方法
把访问了共享数据的代码放到方法中
加synchronized关键字
锁对象是this
1
2
3public synchronized void method(){
}示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class runnable implements Runnable {
private int ticket = 10;
Object obj = new Object();
public void run() {
while (true) {
method();
}
}
public synchronized void method(){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+" "+ticket);
ticket--;
}
else return;
}
}静态同步方法
静态没有this
锁对象:本类的class属性—class文件对象(反射)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class runnable implements Runnable {
private static int ticket = 10;
Object obj = new Object();
public void run() {
while (true) {
method();
}
}
public static synchronized void method(){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+" "+ticket);
ticket--;
}
else return;
}
}
Lock锁接口
包路径
1 | java.util |
方法:
1 | lock()//获取锁 |
步骤:
- 在成员位置创建一个Reentrantlock对象
- 在可能会出现安全问题的代码调用lock()方法
- 在可能会出现安全代码问题之后调用unclock()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class runnable implements Runnable {
private int ticket = 10;
Lock l = new ReentrantLock();
public void run() {
while (true) {
l.lock();
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+" "+ticket);
ticket--;
}
l.unlock();
}
}
}同步技术的原理:
使用了一个锁对象,这个锁对象叫同步锁,也叫对象锁,也叫对象监视器
当发生多线程分享共有资源时,抢到cpu运行权的时候,
运行到synchronize时,检查是否有锁对象,
有,
就会获取到锁对象并进入到同步过程中,运行完归还锁对象。
没有,就会等待直到锁对象被归还。