public class SynchronizedTest implements Runnable
{
private Integer i = new Integer(1); public void a(){
synchronized(i){
i = new Integer(2);
try{
Thread.sleep(5000);
}catch (Exception e){
}
System.out.println("a() i = "+i);
}
} public void b(){
System.out.println("b() i ="+ i);
} public void setI(Integer i){
this.i = i;
} public void run(){
a();
System.out.println("a()---------------");
} public static void main(String[] args){
SynchronizedTest st = new SynchronizedTest(); Thread t = new Thread(st);
t.start();
try{
Thread.sleep(1000);
}catch(Exception e){}
st.b();
st.setI(5);
}
}
/*
*为什么输出结果是
*b() i = 2
*a() i = 5
*a()--------------
*为什么是这样的结果,synchronized(i)不是已经把 i 锁住了吗?怎么还可以修改 i 的值呀?
*/
{
private Integer i = new Integer(1); public void a(){
synchronized(i){
i = new Integer(2);
try{
Thread.sleep(5000);
}catch (Exception e){
}
System.out.println("a() i = "+i);
}
} public void b(){
System.out.println("b() i ="+ i);
} public void setI(Integer i){
this.i = i;
} public void run(){
a();
System.out.println("a()---------------");
} public static void main(String[] args){
SynchronizedTest st = new SynchronizedTest(); Thread t = new Thread(st);
t.start();
try{
Thread.sleep(1000);
}catch(Exception e){}
st.b();
st.setI(5);
}
}
/*
*为什么输出结果是
*b() i = 2
*a() i = 5
*a()--------------
*为什么是这样的结果,synchronized(i)不是已经把 i 锁住了吗?怎么还可以修改 i 的值呀?
*/
锁住 就不会释放了吗????
楼主。先执行 st.b(); 然后 线程醒了 运行 run方法里面的函数 就ok了
<p><textarea cols="50" rows="15" name="code" class="java">public class SynchronizedTest implements Runnable {
private Integer i = new Integer(1);
public void a(Integer i) {
synchronized (i) {
i = new Integer(2);
try {
Thread.sleep(5000);
} catch (Exception e) {
}
System.out.println("a() i = " + i);
}
}
public void b() {
System.out.println("b() i =" + i);
}
public void setI(Integer i) {
this.i = i;
}
public void run() {
a(i);
System.out.println("a()---------------");
}
public static void main(String[] args) {
SynchronizedTest st = new SynchronizedTest();
Thread t = new Thread(st);
t.start();
try {
Thread.sleep(1000);
} catch (Exception e) {
}
st.b();
st.setI(5);
}
}</textarea> </p>
程序应该有两个线程吧,一个 main 线程 一个SynchronizedTest类的线程吗?
1 你的setI中并没有synchronized
2 即使加了synchronized ,也没用,和这个integer类型有关.换成String就成功了
估计应该是integer和int在jdk中已经自动转换了
this.i = i;
}这个方法中也加上synchronized (i)
public void setI(Integer i) {
synchronized (i) {
this.i = i;
}
}这样就可以了
public class SynchronizedTest implements Runnable {
private Integer i = new Integer(1);
private Integer other = new Integer(1); public void a() {
synchronized (other) {
i = new Integer(2);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("a() i = " + i);
}
} public void b() {
System.out.println("b() i =" + i);
} public void setI(Integer num) {
synchronized (other) {
this.i = num;
}
} public void run() {
a();
System.out.println("a()---------------");
} public static void main(String[] args) {
SynchronizedTest st = new SynchronizedTest(); Thread t = new Thread(st);
t.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
st.b();
st.setI(5);
}
}上面的代码有点问题,经过一下以上的bug,测试通过,上面的有些兄弟好像没有理解你的意思 !这样改就可以了
你说为什么可以修改i的值是因为i = new Integer(2);//这个时间监视器(对象锁)不一样了,还有就是你的
public void setI(Integer i){
this.i = i;
}这个方法根本没有同步
public static void main(String[] args) {
Queue q=new Queue ();//new出一个q:后面的两个线程都是用的同一个q,保证一个put一个get
Producer p=new Producer (q);//让new出的p去往q里面put
Customer c=new Customer (q);//让new出的c从q中get
p.start();//p和q开始的顺序并不报错
c.start();
}
}
class Producer extends Thread
{
Queue q;
public Producer(Queue q) {
this.q=q;//给成员变量赋值,再一调运q的put方法
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
q.put(i);//此处只是让q去put 10次
System.out.println("Producer put "+i);//并且输出本次放的是第几杯
}
}
}
class Customer extends Thread
{
Queue q;
public Customer(Queue q) {
this.q=q;//给成员变量赋值,再一调运q的get方法
}
@Override
public void run() {
while (true) {//死循环:只要q里面有,就去get
//get方法有返回值,返回值就是producer所put的数量
//此处也不需要去考虑是第几杯
//在Queue中的value解决可这一问题:
//put中的I赋给value,get方法有返回值就value的值
System.out.println("Customer get "+q.get());
//如果循环完了,就跳出循环,否则线程不会自己结束
if (q.value==9) {
break;
}
}
}
}
class Queue
{
int value;
boolean bFull=false;
public synchronized void put (int i)//在producer中的put方法中就是将其I传进来
{
if (!bFull) {//条件为真(如果没满,就倒水)
value=i;//给value赋值,现在有几杯水
bFull=true;//满了
notify();//唤醒其他线程(让customer去get)
}
try {
wait();//告诉customer去get后自己等待customer的get结束
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized int get()
{
if (!bFull) {//如果没满就等待,如果满了就不进 **这就是为什么main里面谁先开始不报错的原因**
//get和put方法中的if条件判断起到了至关重要的作用
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bFull =false;//赋值为没满
notify();//唤醒producer去put
return value;//get的返回值就是put的时候给value赋的值
}
}
public void setI(Integer i){
synchronized(i)
{
this.i = i;
}
}
我只是不确定我的理解对不,如果哪个人看见了我的回复,请不吝赐教。