本文实例讲述了java线程同步操作。分享给大家供大家参考,具体如下:
java线程同步
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class hello {
public static void main(string[] args) {
myrun myrun0 = new myrun();
new thread(myrun0, "thread0").start();
new thread(myrun0, "thread1").start();
new thread(myrun0, "thread2").start();
}
}
class myrun implements runnable {
private int k = 0;
@override
public void run() {
for (int i = 0; i < 3; i++) {
system.out.println(thread.currentthread().getname() + "**********" + i);
k++;
if (k <= 3) {
if ("thread0".equals(thread.currentthread().getname())) {
try {
thread.sleep(100);
} catch (interruptedexception e) {
e.printstacktrace();
}
}
system.out.println(thread.currentthread().getname() + "," + k);
}
}
}
}
|
输出结果
thread0**********0
thread1**********0
thread2**********0
thread1,2
thread2,3
thread1**********1
thread2**********1
thread2**********2
thread1**********2
thread0,7
thread0**********1
thread0**********2
说明多线程在某些场景是存在问题的,有时候需要线程同步。
同步 synchronized
同步代码块,synchronized(obj){},obj是一个对象,在这里就相当于一把锁,表示一旦有进程抢到了这把锁的钥匙(就是进入了代码块),其他进程将无法进入该锁的代码块(当前代码块其他进程一定是进不来了,其他地方的代码块如果也是用了这把锁,同样进不去),只有代码块执行完,释放锁后,所有进程再重新抢钥匙。
注意,上同一把锁的代码块都会被锁住,这些代码块可能写在不同方法不同位置上。
被同步代码块包住的代码多个线程只能顺次进入。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
synchronized (this) {
k++;
if (k <= 3) {
if ("thread0".equals(thread.currentthread().getname())) {
try {
thread.sleep(100);
} catch (interruptedexception e) {
e.printstacktrace();
}
}
system.out.println(thread.currentthread().getname() + "," + k);
}
}
|
this表示当前对象,这里考虑的只是运行这个方法,不涉及其它类也不涉及这个类的其它地方需要同步问题,所以用this也是可以的。k增加和输出一个流程内只能有一个线程在访问,所以可以得到想要的输出结果
输出结果
thread0**********0
thread1**********0
thread2**********0
thread0,1
thread0**********1
thread2,2
thread2**********1
thread1,3
thread1**********1
thread0**********2
thread2**********2
thread1**********2
对方法进行同步,如果存在多线程,每个线程顺次访问该方法
注意,如果一个类里面存在多个同步方法,那么这些同步方法的锁是一个,都是当前对象,所以不同线程想同时访问同一对象的不同方法也是不行的,因为这些方法都上了同一把锁,但是钥匙只有一把,只能一个线程持有。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@override
public synchronized void run() {
for (int i = 0; i < 3; i++) {
system.out.println(thread.currentthread().getname() + "**********" + i);
k++;
if (k <= 3) {
if ("thread0".equals(thread.currentthread().getname())) {
try {
thread.sleep(100);
} catch (interruptedexception e) {
e.printstacktrace();
}
}
system.out.println(thread.currentthread().getname() + "," + k);
}
}
}
|
输出结果
thread0**********0
thread0,1
thread0**********1
thread0,2
thread0**********2
thread0,3
thread2**********0
thread2**********1
thread2**********2
thread1**********0
thread1**********1
thread1**********2
死锁
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
public class hello {
public static void main(string[] args) {
a a = new a();
b b = new b();
new thread(new myrun(a,b)).start();
new thread(new myrun1(a,b)).start();
}
}
class myrun implements runnable{
private a a;
private b b;
public myrun(a a, b b) {
this.a = a;
this.b = b;
}
@override
public void run(){
a.say(b);
}
}
class myrun1 implements runnable {
private a a;
private b b;
public myrun1(a a, b b) {
this.a = a;
this.b = b;
}
@override
public void run() {
b.say(a);
}
}
class a{
public synchronized void say(b b){
system.out.println("a要知道b的信息");
b.info();
}
public synchronized void info(){
system.out.println("这是a");
}
}
class b{
public synchronized void say(a a){
system.out.println("b要知道a的信息");
a.info();
}
public synchronized void info(){
system.out.println("这是b");
}
}
|
如果两个线程同时进入了两个say方法,就是出现死锁。
关键点在于一个对象的多个同步方法具有相同的锁,都是当前对象。也就是x线程在访问a对象的say方法过程中,y线程是无法访问a对象的info方法的,因为开锁的钥匙已经被x线程抢占了。
上面的程序,如果线程x,y同时进入了两个say方法,a对象同步方法的锁被线程x抢占,b对象同步方法的锁被线程y抢占,此时线程x无法访问b对象的同步方法,线程y无法访问a对象的同步方法。代码中恰好想要访问,所以就出现死锁了。
希望本文所述对大家java程序设计有所帮助。
原文链接:https://blog.csdn.net/shuair/article/details/81906040
相关文章
- 个人服务器网站搭建:如何选择适合自己的建站程序或框架? 2025-06-10
- 64M VPS建站:能否支持高流量网站运行? 2025-06-10
- 64M VPS建站:怎样选择合适的域名和SSL证书? 2025-06-10
- 64M VPS建站:怎样优化以提高网站加载速度? 2025-06-10
- 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
-
2025-05-29 59
-
2025-05-29 51
-
2025-05-29 95
-
2025-06-04 110
-
2025-05-25 91

