public class TicketThread extends Thread {
private volatile int i = 5;
//我的理解是它是多个线程来共享它,不存在拷贝,修改以后必须马上写回。
public void run(){
while(i>0){
i--;
System.out.println(Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TicketThread t1 = new TicketThread();
TicketThread t2 = new TicketThread();
t1.setName("1号窗口");
t2.setName("2号窗口");
t1.start();
t2.start();
}
}
private volatile int i = 5;
//我的理解是它是多个线程来共享它,不存在拷贝,修改以后必须马上写回。
public void run(){
while(i>0){
i--;
System.out.println(Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TicketThread t1 = new TicketThread();
TicketThread t2 = new TicketThread();
t1.setName("1号窗口");
t2.setName("2号窗口");
t1.start();
t2.start();
}
}
解决方案 »
- struts 动态Action问题
- float和Float的区别,floatValue()的作用?
- 关于SWING组件关闭窗体功能的问题
- 为什么JDBC做批量更新速度很慢?
- 在label中加载的图像切换后无法激活~~急求解决方案再加500分都愿意
- udp通讯与servlet整合在一起,可以吗?
- 如何用swing实现类似sql中编辑数据表关系图的界面?
- java面试要注意什么呢?
- 为什么会一直报错 -> 这部分怎么改
- 关于字符流的问题
- 我想请教的是如果我的inputStream对象中的数据比较多,比如几千万个btye,是将b初始化为所有数据长度,调用read方法一次写入所有的数据到数组中但是我
- 递归搜索文件夹
volatile修饰符告诉编译器被volatile修饰的变量可以被程序的其他部分改变。
在多线程程序中,有时两个或更多的线程共享一个相同的实例变量。
一般的变量在多线程中是有copy的,每个线程一个copy.
volatile也不是很可靠
volantile自始至终只有一份拷贝吧。
楼主理解错误。
要精确讲述 volatile作用,还真是要Gosling那个书中的严格叙述方式。我作一个不是很精确的说法:即volatile的变量告诉编译器,该变量可能某种方式(如:多线程)发生改变,因而不能对其作某些假设性的代码安排或代码优化,其结果是:编译器可确保在多线程下,对该变量的读操作或写操作是原子的。楼主的例子是不正确的。因为:i--不是原子操作(它包含了三种操作:读操作,减运算,写操作)因此:只是把i定义为volatile是没有用的。还是会出现错误。
这段话,我还是不能很好的理解。
System.out.println(Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");三个操作使用的是同一个 i。
楼主除了 volatile , 还要使用同步关键字。
我以为加volantile时。
假如上述程序,就是i在线程里没有另外的拷贝产生。
只有一个共享的i.这才说明线程安全。
并不是volatile用错了,而是你创建了两个单独的对象,两个单独的变量,怎么你也达不到共享的效果撒,如果你要达到同步,应该在同一个对象在不同的线程中掉用才对你这样修改一下
TicketThread t1 = new TicketThread();
Thread t11=new Thread(t1,"1号窗口");
Thread t22=new Thread(t1,"2号窗口");
t11.start();
t22.start();
这样就能够达到同步了
1.volatile类型的变量不能依赖上一个结果,比如:int n =0;n=n++;这样就是依赖性的,这样的操作会造成volatile失效。
2.在volatile操作的时候如果有依赖性操作,必须放到同步块中,比如:
public synchronized plus(){
n = n++;
}
这样就能保证了原子的操作。