java synchronized问题 java线程thread对象 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我看到一篇文章上写的 .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法?? 我看到一篇文章上写的 .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法 我看到一篇文章上写的 .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法你重新跑一下 我看到一篇文章上写的 .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法你重新跑一下确实是这样啊 还是有这种情况 结果对啊。CPU在一个时间内只运行一个任务这两个方法交替获得CPU执行 我看到一篇文章上写的 .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法你重新跑一下确实是这样啊 还是有这种情况我跑了好几遍都不是你这个结果 我看到一篇文章上写的 .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法你重新跑一下确实是这样啊 还是有这种情况我跑了好几遍都不是你这个结果为什么我的会出现这种结果? 同一对象的不同线程访问所有的synchronized方法都是同步的吧? 同一个对象 不同线程运行不同的synchronized方法应该是互斥的吧 这是是对象锁啊 同一个对象 做了几次试验,都没有出现过楼主说的那种情况。s1.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }s1.printAge();就算是这样改了,也没出现。 奇怪了 我跑十次有六次出现这样的情况这个结果是正常的。线程的状态有几种创建,可运行,运行,睡眠(等待),死亡s1.start();这个是可运行状态,但是程序不一定在运行,只是先挂起。由于这里时间特别短,所以CPU就有权先运s1.printAge();所以结果就会是你一开始的那种情况。如果照我改的去运行,时间片长了,就会先运行s1.start();这就不会有你说的那种情况了。 恩,如果说sleep()不会释放对象所的话,s1.printAge()是死循环,楼主的第一个输出就是1XXXXXX,说明s1.printAge()已经拿到锁了,那又怎么会再输出age 1:is1呢。不过我试了一下楼主的程序,好像就第一次出现输出1XXX后再输出age 1:is1(也可能看走眼了)。之后又试了好多次,都是在age 9:is1之后再输出1XXX的 sleep()是不会释放对象的锁 也不会让出cpu 但是我试过很多次 很多情况下都是输出1XXX 然后让出对象锁 另外一个线程执行结束 再继续执行原线程 不知道为什么 奇怪了 我跑十次有六次出现这样的情况这个结果是正常的。线程的状态有几种创建,可运行,运行,睡眠(等待),死亡s1.start();这个是可运行状态,但是程序不一定在运行,只是先挂起。由于这里时间特别短,所以CPU就有权先运s1.printAge();所以结果就会是你一开始的那种情况。如果照我改的去运行,时间片长了,就会先运行s1.start();这就不会有你说的那种情况了。不好意思啊 截错图了 是这个结果 不理解 正常情况下应该是Student线程start之后没那么快准备好,主线程不等继续走,所以主线程的一点代码很快执行完了,然后才轮到Student线程。所以一般做这种测试在启动线程之后都需要再Thread.sleep()一下等线程准备好。出来的第一行结果实在没见过,不会是和上次的结果搞串了吧.. 没串啊 上一次结果都清空了的而且设置一个静态变量count 很清楚就能看出不是上一次的运行结果 age 0 is:1age 1 is:11xxxxxxxxxxxxxxxxxxxage 2 is:1age 3 is:1age 4 is:1age 5 is:1age 6 is:1age 7 is:1age 8 is:1age 9 is:11xxxxxxxxxxxxxxxxxxx 和楼主的执行情况不一样。运行下面这个例子class Student extends Thread { private int age; public Student(int age) { this.age = age; } public synchronized void printAge(){ for(int i=0;i<10;i++){ System.err.println("age "+i+" is:"+age); } } public synchronized void printAge(int age) { //synchronized(this){ while (true){ System.out.println(age+"xxxxxxxxxxxxxxxxxxx"); try{ Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } //} } public void run() { printAge(age); }}class Test { public static void main(String args[]) { Student s1 = new Student(1); s1.start(); try{ Thread.sleep(5000);//主线程休眠,然s1线程执行 }catch (InterruptedException e) { e.printStackTrace(); } s1.printAge(); }} 我想我知道问题在哪了,一个线程用的是System.err,一个用的是System.out,这是不同的两个流,eclipse的控制台在输出的时候也许没有处理好,没有实时地输出。说几个方法,你都试试验证下:一个是同样的程序在命令行下测试;一个是统一使用System.out;一个是两个线程里不要输出i,都输出age++然后观察输出结果。 奇怪了 我在实验室运行同样的代码 总是出现交叉输出的 家里的电脑就是同步的 是的 说的很正确 代码改成这样 class Student extends Thread { private int age; public Student(int age) { this.age = age; } public synchronized void printAge() throws InterruptedException{ Thread.sleep(5000); for(int i=0;i<10;i++){ System.err.println("age "+i+" is:"+age); } } public synchronized void printAge(int age) { //synchronized(this){ while (true){ System.out.println(age+"xxxxxxxxxxxxxxxxxxx"); try{ Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } //} } public void run() { printAge(age); }}class Sample { public static void main(String args[]) throws InterruptedException { Student s1 = new Student(1); //s1.start(); s1.printAge(); s1.start(); }}每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。 奇怪了 我在实验室运行同样的代码 总是出现交叉输出的 家里的电脑就是同步的 是的 说的很正确 代码改成这样 class Student extends Thread { private int age; public Student(int age) { this.age = age; } public synchronized void printAge() throws InterruptedException{ Thread.sleep(5000); for(int i=0;i<10;i++){ System.err.println("age "+i+" is:"+age); } } public synchronized void printAge(int age) { //synchronized(this){ while (true){ System.out.println(age+"xxxxxxxxxxxxxxxxxxx"); try{ Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } //} } public void run() { printAge(age); }}class Sample { public static void main(String args[]) throws InterruptedException { Student s1 = new Student(1); //s1.start(); s1.printAge(); s1.start(); }}每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。还是有点不懂 虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊? 奇怪了 我在实验室运行同样的代码 总是出现交叉输出的 家里的电脑就是同步的 是的 说的很正确 代码改成这样 class Student extends Thread { private int age; public Student(int age) { this.age = age; } public synchronized void printAge() throws InterruptedException{ Thread.sleep(5000); for(int i=0;i<10;i++){ System.err.println("age "+i+" is:"+age); } } public synchronized void printAge(int age) { //synchronized(this){ while (true){ System.out.println(age+"xxxxxxxxxxxxxxxxxxx"); try{ Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } //} } public void run() { printAge(age); }}class Sample { public static void main(String args[]) throws InterruptedException { Student s1 = new Student(1); //s1.start(); s1.printAge(); s1.start(); }}每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。还是有点不懂 虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?我先说的最后一点你测试过没有?你代码里的输出只能说是输出顺序,不代表就是执行顺序。同一个流不管怎样肯定会顺序打印,两个流会如何同时打印在一个控制台上那就不确定了。 奇怪了 我在实验室运行同样的代码 总是出现交叉输出的 家里的电脑就是同步的 是的 说的很正确 代码改成这样 class Student extends Thread { private int age; public Student(int age) { this.age = age; } public synchronized void printAge() throws InterruptedException{ Thread.sleep(5000); for(int i=0;i<10;i++){ System.err.println("age "+i+" is:"+age); } } public synchronized void printAge(int age) { //synchronized(this){ while (true){ System.out.println(age+"xxxxxxxxxxxxxxxxxxx"); try{ Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } //} } public void run() { printAge(age); }}class Sample { public static void main(String args[]) throws InterruptedException { Student s1 = new Student(1); //s1.start(); s1.printAge(); s1.start(); }}每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。还是有点不懂 虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?我先说的最后一点你测试过没有?你代码里的输出只能说是输出顺序,不代表就是执行顺序。同一个流不管怎样肯定会顺序打印,两个流会如何同时打印在一个控制台上那就不确定了。明白了 谢谢。 JAVA GUI问题请教大家 java中这个接口是个什么用法? 大量java问题质询 关于JTable中单元格编辑器内容的问题,急!! 数组超界如何解决 一个关于newInstance简单的java小问题!!! 求助:如何替换字符串中的反斜杠 请问哪里于关于package设置的文章 非常简单的swing问题 新手求教基本方法 java设置日期格式 注册窗口 注册后or关闭后再打开 数据无法清空
.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
你重新跑一下
.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
你重新跑一下确实是这样啊 还是有这种情况
.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
你重新跑一下确实是这样啊 还是有这种情况
我跑了好几遍都不是你这个结果
.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
你重新跑一下确实是这样啊 还是有这种情况
我跑了好几遍都不是你这个结果
为什么我的会出现这种结果? 同一对象的不同线程访问所有的synchronized方法都是同步的吧?
s1.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s1.printAge();
就算是这样改了,也没出现。
奇怪了 我跑十次有六次出现这样的情况
这个结果是正常的。
线程的状态有几种
创建,可运行,运行,睡眠(等待),死亡
s1.start();这个是可运行状态,但是程序不一定在运行,只是先挂起。由于这里时间特别短,所以CPU就有权先运s1.printAge();所以结果就会是你一开始的那种情况。如果照我改的去运行,时间片长了,就会先运行s1.start();这就不会有你说的那种情况了。
不过我试了一下楼主的程序,好像就第一次出现输出1XXX后再输出age 1:is1(也可能看走眼了)。之后又试了好多次,都是在age 9:is1之后再输出1XXX的
sleep()是不会释放对象的锁 也不会让出cpu
但是我试过很多次 很多情况下都是输出1XXX 然后让出对象锁 另外一个线程执行结束 再继续执行原线程 不知道为什么
奇怪了 我跑十次有六次出现这样的情况
这个结果是正常的。
线程的状态有几种
创建,可运行,运行,睡眠(等待),死亡
s1.start();这个是可运行状态,但是程序不一定在运行,只是先挂起。由于这里时间特别短,所以CPU就有权先运s1.printAge();所以结果就会是你一开始的那种情况。如果照我改的去运行,时间片长了,就会先运行s1.start();这就不会有你说的那种情况了。不好意思啊 截错图了 是这个结果 不理解
出来的第一行结果实在没见过,不会是和上次的结果搞串了吧..
而且设置一个静态变量count 很清楚就能看出不是上一次的运行结果
age 1 is:11xxxxxxxxxxxxxxxxxxxage 2 is:1
age 3 is:1
age 4 is:1
age 5 is:1
age 6 is:1
age 7 is:1
age 8 is:1
age 9 is:1
1xxxxxxxxxxxxxxxxxxx
运行下面这个例子
class Student extends Thread {
private int age; public Student(int age) {
this.age = age;
} public synchronized void printAge(){
for(int i=0;i<10;i++){
System.err.println("age "+i+" is:"+age);
}
}
public synchronized void printAge(int age) {
//synchronized(this){
while (true){
System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
} public void run() {
printAge(age);
}
}class Test {
public static void main(String args[]) {
Student s1 = new Student(1);
s1.start();
try{
Thread.sleep(5000);//主线程休眠,然s1线程执行
}catch (InterruptedException e) {
e.printStackTrace();
}
s1.printAge();
}
}
是的 说的很正确 代码改成这样
class Student extends Thread {
private int age; public Student(int age) {
this.age = age;
} public synchronized void printAge() throws InterruptedException{
Thread.sleep(5000);
for(int i=0;i<10;i++){
System.err.println("age "+i+" is:"+age);
}
}
public synchronized void printAge(int age) {
//synchronized(this){
while (true){
System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
} public void run() {
printAge(age);
}
}class Sample {
public static void main(String args[]) throws InterruptedException {
Student s1 = new Student(1);
//s1.start();
s1.printAge();
s1.start();
}
}
每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。
是的 说的很正确 代码改成这样
class Student extends Thread {
private int age; public Student(int age) {
this.age = age;
} public synchronized void printAge() throws InterruptedException{
Thread.sleep(5000);
for(int i=0;i<10;i++){
System.err.println("age "+i+" is:"+age);
}
}
public synchronized void printAge(int age) {
//synchronized(this){
while (true){
System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
} public void run() {
printAge(age);
}
}class Sample {
public static void main(String args[]) throws InterruptedException {
Student s1 = new Student(1);
//s1.start();
s1.printAge();
s1.start();
}
}
每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。还是有点不懂 虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?
是的 说的很正确 代码改成这样
class Student extends Thread {
private int age; public Student(int age) {
this.age = age;
} public synchronized void printAge() throws InterruptedException{
Thread.sleep(5000);
for(int i=0;i<10;i++){
System.err.println("age "+i+" is:"+age);
}
}
public synchronized void printAge(int age) {
//synchronized(this){
while (true){
System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
} public void run() {
printAge(age);
}
}class Sample {
public static void main(String args[]) throws InterruptedException {
Student s1 = new Student(1);
//s1.start();
s1.printAge();
s1.start();
}
}
每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。还是有点不懂 虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?我先说的最后一点你测试过没有?你代码里的输出只能说是输出顺序,不代表就是执行顺序。同一个流不管怎样肯定会顺序打印,两个流会如何同时打印在一个控制台上那就不确定了。
是的 说的很正确 代码改成这样
class Student extends Thread {
private int age; public Student(int age) {
this.age = age;
} public synchronized void printAge() throws InterruptedException{
Thread.sleep(5000);
for(int i=0;i<10;i++){
System.err.println("age "+i+" is:"+age);
}
}
public synchronized void printAge(int age) {
//synchronized(this){
while (true){
System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
} public void run() {
printAge(age);
}
}class Sample {
public static void main(String args[]) throws InterruptedException {
Student s1 = new Student(1);
//s1.start();
s1.printAge();
s1.start();
}
}
每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了 就是同步了。。还是有点不懂 虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?我先说的最后一点你测试过没有?你代码里的输出只能说是输出顺序,不代表就是执行顺序。同一个流不管怎样肯定会顺序打印,两个流会如何同时打印在一个控制台上那就不确定了。
明白了 谢谢。