Cirry's Blog

线程的同步与死锁

2019-10-08
技术
java
最后更新:2024-03-22
5分钟
856字

在多线程的处理中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,于是当多个线程访问同一资源的时候,如果处理不当就会产生数据的错误操作。 同步问题的引出 下面编写一个简单的卖票程序,将创建若干个线程对象实现卖票的处理操作。 范例:

1
package cn.cccc.demo;
2
class MyThread implements Runnable{
3
private int ticket = 10; //总票数为十张
4
public void run(){
5
while(true){
6
if(this.ticket > 0 ){
7
try {
8
Thread.sleep(100);
9
} catch (InterruptedException e) {
10
// TODO Auto-generated catch block
11
e.printStackTrace();
12
}//模拟网络延迟
13
System.out.println(Thread.currentThread().getName()+ "卖票,ticket"+ this.ticket -- );
14
}else {
15
System.out.println("票已卖完");
13 collapsed lines
16
break;
17
}
18
}
19
}
20
}
21
public class ThreadDemo {
22
public static void main(String[] args) throws Exception {
23
MyThread mt = new MyThread();
24
new Thread(mt, "票贩子A").start();
25
new Thread(mt, "票贩子B").start();
26
new Thread(mt, "票贩子C").start();
27
}
28
}

票贩子A卖票,ticket10 票贩子B卖票,ticket9 票贩子C卖票,ticket8 票贩子A卖票,ticket7 票贩子B卖票,ticket6 票贩子C卖票,ticket6 票贩子A卖票,ticket5 票贩子B卖票,ticket4 票贩子C卖票,ticket3 票贩子A卖票,ticket2 票贩子C卖票,ticket1 票贩子B卖票,ticket0 票已卖完 票已卖完 票贩子A卖票,ticket-1 票已卖完

线程同步:解决同步问题的关键是锁,指的是当某一个线程执行操作的时候,其他线程外面等待。synchronized关键字来实现来同步。 利用同步代码块进行处理 synchronized(同步对象){ 同步代码操作; } 一般要进行同步对象处理的时候,可以采用当前对象this进行同步 范例:利用同步代码块解决数据同步访问的问题

1
package cn.cccc.demo;
2
class MyThread implements Runnable{
3
private int ticket = 10; //总票数为十张
4
public void run(){
5
while(true){
6
synchronized (this) { //每一次只允许一个线程进行访问
7
if(this.ticket > 0 ){
8
try {
9
Thread.sleep(100);
10
} catch (InterruptedException e) {
11
// TODO Auto-generated catch block
12
e.printStackTrace();
13
}//模拟网络延迟
14
System.out.println(Thread.currentThread().getName()+ "卖票,ticket"+ this.ticket -- );
15
}else {
15 collapsed lines
16
System.out.println("票已卖完");
17
break;
18
}
19
}
20
}
21
}
22
}
23
public class ThreadDemo {
24
public static void main(String[] args) throws Exception {
25
MyThread mt = new MyThread();
26
new Thread(mt, "票贩子A").start();
27
new Thread(mt, "票贩子B").start();
28
new Thread(mt, "票贩子C").start();
29
}
30
}

加入同步处理之后,程序的整体性能下降了。同步实际上会造成性能的降低。

利用同步方法解决:只需要在方法定义上使用synchronized关键字即可。

1
package cn.cccc.demo;
2
class MyThread implements Runnable{
3
private int ticket = 10; //总票数为十张
4
public synchronized boolean sale(){
5
if(this.ticket > 0 ){
6
try {
7
Thread.sleep(100);
8
} catch (InterruptedException e) {
9
// TODO Auto-generated catch block
10
e.printStackTrace();
11
}//模拟网络延迟
12
System.out.println(Thread.currentThread().getName()+ "卖票,ticket"+ this.ticket -- );
13
return true;
14
}else {
15
System.out.println("票已卖完");
17 collapsed lines
16
return false;
17
}
18
}
19
public void run(){
20
while(this.sale()){
21
;
22
}
23
}
24
}
25
public class ThreadDemo {
26
public static void main(String[] args) throws Exception {
27
MyThread mt = new MyThread();
28
new Thread(mt, "票贩子A").start();
29
new Thread(mt, "票贩子B").start();
30
new Thread(mt, "票贩子C").start();
31
}
32
}

在以后学习java类库的时候回发现,系统中许多类上使用的同步处理采用的都是同步方法。

线程死锁 死锁是在进行多线程同步的处理之中有可能产生的一种问题,所谓的死锁指的是若干个线程彼此互相等待的状态。 若干个线程访问同一资源时一定要进行同步处理,而过多的同步会造成死锁。

本文标题:线程的同步与死锁
文章作者:Cirry
发布时间:2019-10-08
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
感谢大佬送来的咖啡☕
alipayQRCode
wechatQRCode