当前位置:编程学习 > JAVA >>

java线程,同步问题

public class X implements Runnable{
private int x;
private int y;
public static void main(String[] args) {
X that = new X();
(new Thread(that)).start();
(new Thread(that)).start();
}
public synchronized void run(){
for(;;){
x++;
y++;
System.out.println("x = "+x+",y = "+y);
}
}
}

哪位大神能帮我分析一下这道题的执行过程,谢谢啦!!! --------------------编程问答-------------------- 这个程序有三个线程。因为X类里面的run()方法是同步方法,当此方法被新建的两个线程调用的是时候,他们要获取that对象的对象锁,两个线程只有一个线程能获取此锁,另外的那个线程只能等待获取该锁而阻塞。由于run()方法里面是个死循环,获取锁的那个线程一直结束不了,也就永远释放不了那个锁,另外的那个线程也就会一直等下去。也就是这个程序只有主线程和获取锁的那个线程能执行,另外的那个线程因为得不到对象锁,一直等待。 --------------------编程问答-------------------- 楼主你用 for(;;) 的话,x y 的值变得没有初始化。换成for(int i=0; i<200; i++) x, y 才有初始化

多线程就是有多个用户在请求资源,楼主你只 new 一个对象,没法体现多线程同步。应该多创建一个对象
synchronized只对对象有效,所以不同线程对同一个类产生的不同对象中的sycn方法的访问不受限制。

在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问 --------------------编程问答-------------------- 对于同步问题的多线程,楼主可以看下这个代码。
package bbs0916;

public class X implements Runnable {
private int x;
private int y;

public static X that1 = new X();
public static X that2 = new X();

public static void main(String[] args) {
(new Thread(that1)).start();
(new Thread(that2)).start();
}

public synchronized void run() {
for (int i=0; i<100; i++) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
}
}
}
--------------------编程问答--------------------
引用 1 楼 u011540494 的回复:
这个程序有三个线程。因为X类里面的run()方法是同步方法,当此方法被新建的两个线程调用的是时候,他们要获取that对象的对象锁,两个线程只有一个线程能获取此锁,另外的那个线程只能等待获取该锁而阻塞。由于run()方法里面是个死循环,获取锁的那个线程一直结束不了,也就永远释放不了那个锁,另外的那个线程也就会一直等下去。也就是这个程序只有主线程和获取锁的那个线程能执行,另外的那个线程因为得不到对象锁,一直等待。
似乎明白了一点,再想想。 --------------------编程问答-------------------- x和y是什么时候赋值的呢?X类中并没有getXxx()和setXxx()方法啊。。。 --------------------编程问答-------------------- 这个for(;;)相当于while(true),导致谁先抢到了线程锁,谁就会一直运行下去,不会让出这个锁(that) --------------------编程问答--------------------
引用 3 楼 a1006570862 的回复:
对于同步问题的多线程,楼主可以看下这个代码。
package bbs0916;

public class X implements Runnable {
private int x;
private int y;

public static X that1 = new X();
public static X that2 = new X();

public static void main(String[] args) {
(new Thread(that1)).start();
(new Thread(that2)).start();
}

public synchronized void run() {
for (int i=0; i<100; i++) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
}
}
}
一个是一个对象,一个是两个对象。 --------------------编程问答--------------------
引用 5 楼 shirui8653719 的回复:
x和y是什么时候赋值的呢?X类中并没有getXxx()和setXxx()方法啊。。。


在创建that对象时,int型的成员变量会被自动初始化为0. --------------------编程问答--------------------
引用 3 楼 a1006570862 的回复:
对于同步问题的多线程,楼主可以看下这个代码。
package bbs0916;

public class X implements Runnable {
private int x;
private int y;

public static X that1 = new X();
public static X that2 = new X();

public static void main(String[] args) {
(new Thread(that1)).start();
(new Thread(that2)).start();
}

public synchronized void run() {
for (int i=0; i<100; i++) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
}
}
}

这段代码的执行结果:x = 1,y = 1
x = 2,y = 2
x = 3,y = 3
x = 4,y = 4
x = 5,y = 5
x = 6,y = 6
x = 7,y = 7
x = 8,y = 8
x = 9,y = 9
x = 10,y = 10
x = 11,y = 11
x = 12,y = 12
x = 13,y = 13
x = 14,y = 14
x = 15,y = 15
x = 16,y = 16
x = 17,y = 17
x = 18,y = 18
x = 19,y = 19
x = 20,y = 20
x = 21,y = 21
x = 22,y = 22
x = 23,y = 23
x = 24,y = 24
x = 25,y = 25
x = 26,y = 26
x = 27,y = 27
x = 28,y = 28
x = 29,y = 29
x = 30,y = 30
x = 31,y = 31
x = 32,y = 32
x = 33,y = 33
x = 34,y = 34
x = 35,y = 35
x = 36,y = 36
x = 37,y = 37
x = 38,y = 38
x = 39,y = 39
x = 40,y = 40
x = 41,y = 41
x = 42,y = 42
x = 43,y = 43
x = 44,y = 44
x = 45,y = 45
x = 1,y = 1
x = 46,y = 46
x = 2,y = 2
x = 47,y = 47
x = 3,y = 3
x = 48,y = 48
x = 4,y = 4
x = 49,y = 49
x = 5,y = 5
x = 50,y = 50
x = 6,y = 6
x = 51,y = 51
x = 7,y = 7
x = 52,y = 52
x = 8,y = 8
x = 53,y = 53
x = 9,y = 9
x = 54,y = 54
x = 10,y = 10
请问第一个线程没有结束,第二个线程已经开始工作了? --------------------编程问答--------------------
引用 9 楼 qq864680621 的回复:
Quote: 引用 3 楼 a1006570862 的回复:

对于同步问题的多线程,楼主可以看下这个代码。
package bbs0916;

public class X implements Runnable {
private int x;
private int y;

public static X that1 = new X();
public static X that2 = new X();

public static void main(String[] args) {
(new Thread(that1)).start();
(new Thread(that2)).start();
}

public synchronized void run() {
for (int i=0; i<100; i++) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
}
}
}

这段代码的执行结果:x = 1,y = 1
x = 2,y = 2
x = 3,y = 3
x = 4,y = 4
x = 5,y = 5
x = 6,y = 6
x = 7,y = 7
x = 8,y = 8
x = 9,y = 9
x = 10,y = 10
x = 11,y = 11
x = 12,y = 12
x = 13,y = 13
x = 14,y = 14
x = 15,y = 15
x = 16,y = 16
x = 17,y = 17
x = 18,y = 18
x = 19,y = 19
x = 20,y = 20
x = 21,y = 21
x = 22,y = 22
x = 23,y = 23
x = 24,y = 24
x = 25,y = 25
x = 26,y = 26
x = 27,y = 27
x = 28,y = 28
x = 29,y = 29
x = 30,y = 30
x = 31,y = 31
x = 32,y = 32
x = 33,y = 33
x = 34,y = 34
x = 35,y = 35
x = 36,y = 36
x = 37,y = 37
x = 38,y = 38
x = 39,y = 39
x = 40,y = 40
x = 41,y = 41
x = 42,y = 42
x = 43,y = 43
x = 44,y = 44
x = 45,y = 45
x = 1,y = 1
x = 46,y = 46
x = 2,y = 2
x = 47,y = 47
x = 3,y = 3
x = 48,y = 48
x = 4,y = 4
x = 49,y = 49
x = 5,y = 5
x = 50,y = 50
x = 6,y = 6
x = 51,y = 51
x = 7,y = 7
x = 52,y = 52
x = 8,y = 8
x = 53,y = 53
x = 9,y = 9
x = 54,y = 54
x = 10,y = 10
请问第一个线程没有结束,第二个线程已经开始工作了?
我的想法是new了两个对象,两个对象可以各自进行自己的线程,不知道我考虑的对不对。 --------------------编程问答-------------------- 我的想法是new了两个对象,两个对象可以各自进行自己的线程,不知道我考虑的对不对。 
两个对象用的是一个线程吧 --------------------编程问答-------------------- 从打印的信息看,两个线程各自有各自的x,y,数据没有共享;

我个人的看法,多线程数据同步应该是多个线程可访问相同的内存地址以获取相同的数据(可能的情况下,需要做出修改)。以楼主给出的代码看,两个Thread是各自new的,用到的x,y变量名相同,但各自分配的内存区域并不一致。虽然使用了synchronized,只是这个方法的运行要排队,但打印的数据不是相同的,所以出现了两个线程打印各自数据的情况。

就像一条流水线,线程1输入的是x1、y1;线程2输入的是x2,y2;
流水线每次只能对输入一组进行组装,
每次输入的是不同的数据组,输出的产品也就是各自的打印。
没有实现楼主所期望的同步 --------------------编程问答--------------------
引用 1 楼 u011540494 的回复:
这个程序有三个线程。因为X类里面的run()方法是同步方法,当此方法被新建的两个线程调用的是时候,他们要获取that对象的对象锁,两个线程只有一个线程能获取此锁,另外的那个线程只能等待获取该锁而阻塞。由于run()方法里面是个死循环,获取锁的那个线程一直结束不了,也就永远释放不了那个锁,另外的那个线程也就会一直等下去。也就是这个程序只有主线程和获取锁的那个线程能执行,另外的那个线程因为得不到对象锁,一直等待。

+1 --------------------编程问答--------------------
引用 10 楼 shirui8653719 的回复:
Quote: 引用 9 楼 qq864680621 的回复:

Quote: 引用 3 楼 a1006570862 的回复:

对于同步问题的多线程,楼主可以看下这个代码。
package bbs0916;

public class X implements Runnable {
private int x;
private int y;

public static X that1 = new X();
public static X that2 = new X();

public static void main(String[] args) {
(new Thread(that1)).start();
(new Thread(that2)).start();
}

public synchronized void run() {
for (int i=0; i<100; i++) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
}
}
}

这段代码的执行结果:x = 1,y = 1
x = 2,y = 2
x = 3,y = 3
x = 4,y = 4
x = 5,y = 5
x = 6,y = 6
x = 7,y = 7
x = 8,y = 8
x = 9,y = 9
x = 10,y = 10
x = 11,y = 11
x = 12,y = 12
x = 13,y = 13
x = 14,y = 14
x = 15,y = 15
x = 16,y = 16
x = 17,y = 17
x = 18,y = 18
x = 19,y = 19
x = 20,y = 20
x = 21,y = 21
x = 22,y = 22
x = 23,y = 23
x = 24,y = 24
x = 25,y = 25
x = 26,y = 26
x = 27,y = 27
x = 28,y = 28
x = 29,y = 29
x = 30,y = 30
x = 31,y = 31
x = 32,y = 32
x = 33,y = 33
x = 34,y = 34
x = 35,y = 35
x = 36,y = 36
x = 37,y = 37
x = 38,y = 38
x = 39,y = 39
x = 40,y = 40
x = 41,y = 41
x = 42,y = 42
x = 43,y = 43
x = 44,y = 44
x = 45,y = 45
x = 1,y = 1
x = 46,y = 46
x = 2,y = 2
x = 47,y = 47
x = 3,y = 3
x = 48,y = 48
x = 4,y = 4
x = 49,y = 49
x = 5,y = 5
x = 50,y = 50
x = 6,y = 6
x = 51,y = 51
x = 7,y = 7
x = 52,y = 52
x = 8,y = 8
x = 53,y = 53
x = 9,y = 9
x = 54,y = 54
x = 10,y = 10
请问第一个线程没有结束,第二个线程已经开始工作了?
我的想法是new了两个对象,两个对象可以各自进行自己的线程,不知道我考虑的对不对。


你的想法是两个对象个自己进行征集的线程
你看下我代码执行的结果就是两个线程各自运行,你看到有两个 x = 1, y = 1 。如果是你的代码的话就相互干扰了,直接加到 x = 20, y = 20 了 --------------------编程问答--------------------
引用 14 楼 a1006570862 的回复:
Quote: 引用 10 楼 shirui8653719 的回复:

Quote: 引用 9 楼 qq864680621 的回复:

Quote: 引用 3 楼 a1006570862 的回复:

对于同步问题的多线程,楼主可以看下这个代码。
package bbs0916;

public class X implements Runnable {
private int x;
private int y;

public static X that1 = new X();
public static X that2 = new X();

public static void main(String[] args) {
(new Thread(that1)).start();
(new Thread(that2)).start();
}

public synchronized void run() {
for (int i=0; i<100; i++) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
}
}
}

这段代码的执行结果:x = 1,y = 1
x = 2,y = 2
x = 3,y = 3
x = 4,y = 4
x = 5,y = 5
x = 6,y = 6
x = 7,y = 7
x = 8,y = 8
x = 9,y = 9
x = 10,y = 10
x = 11,y = 11
x = 12,y = 12
x = 13,y = 13
x = 14,y = 14
x = 15,y = 15
x = 16,y = 16
x = 17,y = 17
x = 18,y = 18
x = 19,y = 19
x = 20,y = 20
x = 21,y = 21
x = 22,y = 22
x = 23,y = 23
x = 24,y = 24
x = 25,y = 25
x = 26,y = 26
x = 27,y = 27
x = 28,y = 28
x = 29,y = 29
x = 30,y = 30
x = 31,y = 31
x = 32,y = 32
x = 33,y = 33
x = 34,y = 34
x = 35,y = 35
x = 36,y = 36
x = 37,y = 37
x = 38,y = 38
x = 39,y = 39
x = 40,y = 40
x = 41,y = 41
x = 42,y = 42
x = 43,y = 43
x = 44,y = 44
x = 45,y = 45
x = 1,y = 1
x = 46,y = 46
x = 2,y = 2
x = 47,y = 47
x = 3,y = 3
x = 48,y = 48
x = 4,y = 4
x = 49,y = 49
x = 5,y = 5
x = 50,y = 50
x = 6,y = 6
x = 51,y = 51
x = 7,y = 7
x = 52,y = 52
x = 8,y = 8
x = 53,y = 53
x = 9,y = 9
x = 54,y = 54
x = 10,y = 10
请问第一个线程没有结束,第二个线程已经开始工作了?
我的想法是new了两个对象,两个对象可以各自进行自己的线程,不知道我考虑的对不对。


你的想法是两个对象个自己进行征集的线程
你看下我代码执行的结果就是两个线程各自运行,你看到有两个 x = 1, y = 1 。如果是你的代码的话就相互干扰了,直接加到 x = 20, y = 20 了
这样的话synchronized关键字就失效了啊,对吧? --------------------编程问答--------------------
引用 11 楼 qq864680621 的回复:
我的想法是new了两个对象,两个对象可以各自进行自己的线程,不知道我考虑的对不对。 
两个对象用的是一个线程吧

(new Thread(that)).start();
        (new Thread(that)).start();

这句话应该是两个线程吧。 --------------------编程问答--------------------
引用 12 楼 losebaby 的回复:
从打印的信息看,两个线程各自有各自的x,y,数据没有共享;

我个人的看法,多线程数据同步应该是多个线程可访问相同的内存地址以获取相同的数据(可能的情况下,需要做出修改)。以楼主给出的代码看,两个Thread是各自new的,用到的x,y变量名相同,但各自分配的内存区域并不一致。虽然使用了synchronized,只是这个方法的运行要排队,但打印的数据不是相同的,所以出现了两个线程打印各自数据的情况。

就像一条流水线,线程1输入的是x1、y1;线程2输入的是x2,y2;
流水线每次只能对输入一组进行组装,
每次输入的是不同的数据组,输出的产品也就是各自的打印。
没有实现楼主所期望的同步
嗯,这个解释比较合理。 --------------------编程问答-------------------- lz试一下下面的代码。
public class X implements Runnable {
private int x;
private int y;

public static void main(String[] args) {

X that = new X();
Thread t1 = new Thread(that);
Thread t2 = new Thread(that);
t1.start();
t2.start();
System.out.println("over");

}
public synchronized void run() {
for (;;) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
try {
System.out.println(Thread.currentThread());
wait(3000);
//Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
--------------------编程问答--------------------
引用 18 楼 u011540494 的回复:
lz试一下下面的代码。
public class X implements Runnable {
private int x;
private int y;

public static void main(String[] args) {

X that = new X();
Thread t1 = new Thread(that);
Thread t2 = new Thread(that);
t1.start();
t2.start();
System.out.println("over");

}
public synchronized void run() {
for (;;) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
try {
System.out.println(Thread.currentThread());
wait(3000);
//Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


引用 18 楼 u011540494 的回复:
lz试一下下面的代码。
public class X implements Runnable {
private int x;
private int y;

public static void main(String[] args) {

X that = new X();
Thread t1 = new Thread(that);
Thread t2 = new Thread(that);
t1.start();
t2.start();
System.out.println("over");

}
public synchronized void run() {
for (;;) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
try {
System.out.println(Thread.currentThread());
wait(3000);
//Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

输出的结果是为什么是两个线程同时工作,那synchronized关键字不是没起作用吗? --------------------编程问答--------------------
引用 19 楼 shirui8653719 的回复:
Quote: 引用 18 楼 u011540494 的回复:

lz试一下下面的代码。
public class X implements Runnable {
private int x;
private int y;

public static void main(String[] args) {

X that = new X();
Thread t1 = new Thread(that);
Thread t2 = new Thread(that);
t1.start();
t2.start();
System.out.println("over");

}
public synchronized void run() {
for (;;) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
try {
System.out.println(Thread.currentThread());
wait(3000);
//Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


引用 18 楼 u011540494 的回复:
lz试一下下面的代码。
public class X implements Runnable {
private int x;
private int y;

public static void main(String[] args) {

X that = new X();
Thread t1 = new Thread(that);
Thread t2 = new Thread(that);
t1.start();
t2.start();
System.out.println("over");

}
public synchronized void run() {
for (;;) {
x++;
y++;
System.out.println("x = " + x + ",y = " + y);
try {
System.out.println(Thread.currentThread());
wait(3000);
//Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

输出的结果是为什么是两个线程同时工作,那synchronized关键字不是没起作用吗?

wait(3000)使当前线程阻塞并释放了对象锁,另外的那个线程获取了对象锁之后就可以从阻塞状态变为执行状态了。
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,