synchronized(this)
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。
解决方案 »
- struts的ognl问题
- 想交几位"尚学堂"毕业的学生请教和探讨IT学术问题……
- 买什么书好?!!!
- 一个页面可以同时向两个SERVLET提交数据吗?
- 有关LookUpDispatchAction和中文的问题
- 求助:如何用Corba客户端(java代码)访问EJB?(50分求助)
- Java中把一个String转换成unicode怎么办!
- 请问在JAVA里如何将字符型转化为日期型?
- 实战EJB之四(开发实体CMP),在部署应用程序的时候,点击"实体EJB的持续性管理",”在设置数据源的JNDI名时,如何修改datasources.xml来
- JAVA怎么刷新物化视图呢?困惑困惑困惑困惑困惑困惑
- 急求关于Struts的解决方案
- 求助,各位大牛们,请问如何快速用java进行开发
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。就像楼上说的,你这不是锁,要锁住就用synchronized,另外jdk的java.util.current包下还有一些信号灯之类的东西,也很不错,多看看学学吧!
SellTicketSystem s1 = new SellTicketSystem();
SellTicketSystem s2 = new SellTicketSystem();
s1.setName("111");
s2.setName("2222222222"); s1.start();
s2.start();
}
}class SellTicketSystem extends Thread {
private static int ticket = 20;
private static byte[] b = new byte[] { 1 }; public void run() {
while (true) {
if (ticket > 0) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println(this.getName() + "卖到第" + ticket-- + "张");
}
}
}
}}
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了
你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了
你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)哥们儿,不知道你运行了没有这tickit--是先执行,再减1,最后tickit的值是-1,不是0,懂否???
222222222不卖票的原因是锁的位置不对,一个线程一直占用,一直到票卖光了,另一个线程才能执行锁内的代码。public class Demo2{
public static void main(String [] args){
Stack stack = new Stack();
SellTicketSystem s1 = new SellTicketSystem(stack,"111");
SellTicketSystem s2 = new SellTicketSystem(stack,"2222222222");
s1.start();
s2.start();
}
}
//共享数据
class Stack{
public int ticket=20;
public synchronized void sell(String name) {
int t = ticket--;
System.out.println(name+"卖到第"+t+"张");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
class SellTicketSystem extends Thread{
private Stack stack;
private String name;
public SellTicketSystem(Stack stack,String name){
super();
this.stack = stack;
this.name = name;
}
public void run(){
while (stack.ticket>0) {
this.stack.sell(this.name);
}
}
}
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了
你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)哥们儿,不知道你运行了没有这tickit--是先执行,再减1,最后tickit的值是-1,不是0,懂否???ticket==1
输出ticket--时,打印的是1好不,但这时ticket的值变成了0;!!
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了111运行时加上锁,用运行一圈后,你没有解锁,所以2222222跟本得不到资源,怎么运行???这个程序实现就是让他你一下,我一下,你一下,我一下,这样就要来回的加锁解锁,加锁解锁,你这有加锁,跟本没解锁啊,用一下信号灯吧,去网看一下有关知识,实现更简单
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了
你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)哥们儿,不知道你运行了没有这tickit--是先执行,再减1,最后tickit的值是-1,不是0,懂否???ticket==1
输出ticket--时,打印的是1好不,但这时ticket的值变成了0;!!对啊,这没错啊,然后下一轮得到的就是0了啊,这跟本不是ticket--的问题啊,买了票后,当然少一张票,所以这个写法没问题,有问题的还是线程同步上,楼主得到的2一下,1一下,来回交换只是一个巧合,巧合而已
if(ticket>0)这个判断条件加上 ticket-- 这个输出肯定是会出现0的啊,如果ticket==1>0,自然满足条件然后输出 ticket-- = 0 不是很正常吗
你执行下一段代码先试一试再说.
int ticket = 1;
if(ticket>0){
//这时1>0,所以能进来
System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
}
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
111卖到第20张
111卖到第19张
111卖到第18张
111卖到第17张
111卖到第16张
111卖到第15张
111卖到第14张
111卖到第13张
111卖到第12张
111卖到第11张
111卖到第10张
111卖到第9张
111卖到第8张
111卖到第7张
111卖到第6张
111卖到第5张
111卖到第4张
111卖到第3张
111卖到第2张
111卖到第1张
这样的话222222222就卖不了票了111运行时加上锁,用运行一圈后,你没有解锁,所以2222222跟本得不到资源,怎么运行???这个程序实现就是让他你一下,我一下,你一下,我一下,这样就要来回的加锁解锁,加锁解锁,你这有加锁,跟本没解锁啊,用一下信号灯吧,去网看一下有关知识,实现更简单
那有什么实现的方法么?
你执行下一段代码先试一试再说.
int ticket = 1;
if(ticket>0){
//这时1>0,所以能进来
System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
}额是的,我粗心了,ticket--实际上是先输出ticket然后再执行ticket--的,说明线程A和线程B在ticket==1的时候同时进来,然后A把ticket--了,而B仍然输出ticket,此时就输出了被A减过的ticket就是0
222222222不卖票的原因是锁的位置不对,一个线程一直占用,一直到票卖光了,另一个线程才能执行锁内的代码。public class Demo2{
public static void main(String [] args){
Stack stack = new Stack();
SellTicketSystem s1 = new SellTicketSystem(stack,"111");
SellTicketSystem s2 = new SellTicketSystem(stack,"2222222222");
s1.start();
s2.start();
}
}
//共享数据
class Stack{
public int ticket=20;
public synchronized void sell(String name) {
int t = ticket--;
System.out.println(name+"卖到第"+t+"张");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
class SellTicketSystem extends Thread{
private Stack stack;
private String name;
public SellTicketSystem(Stack stack,String name){
super();
this.stack = stack;
this.name = name;
}
public void run(){
while (stack.ticket>0) {
this.stack.sell(this.name);
}
}
}
为什么是全部是从20张票减少,而不是各自减去各自的
你执行下一段代码先试一试再说.
int ticket = 1;
if(ticket>0){
//这时1>0,所以能进来
System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
}关键是要执行原子操作,而while(true)这段代码无法保证整个都是原子性的,因为ticket==1的时候A和B线程可以同时有效,然后我自定义了一组信号量,可以保证A和B交替执行并且最后ticket不为0
public static class Demo2{ public static void main(String [] args){
SellTicketSystem s1 = new SellTicketSystem();
SellTicketSystem s2 = new SellTicketSystem();
s1.setName("111");
s2.setName("2222222222");
//System.out.println("sdsd");
s1.start();
s2.start();
}
}
static class SellTicketSystem extends Thread{
private static int mutex = 1;
private static String name = "2222222222";//另一个线程先开始
private boolean _wait(){
//确保上一次另一个线程拿到了资源
if(mutex==1 && !name.equals(this.getName())){
name = this.getName();
mutex--;
return true;
}else{
return false;
}
}
private void _signal(){
if(mutex==0 && ticket>0){
mutex++;
}
}
private static int ticket=20;
public void run(){
while(ticket>0){
if(ticket>0){
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
if(_wait()){
System.out.println(this.getName()+"卖到第"+ticket--+"张");
_signal();
}
}
}
}}
你执行下一段代码先试一试再说.
int ticket = 1;
if(ticket>0){
//这时1>0,所以能进来
System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
}关键是要执行原子操作,而while(true)这段代码无法保证整个都是原子性的,因为ticket==1的时候A和B线程可以同时有效,然后我自定义了一组信号量,可以保证A和B交替执行并且最后ticket不为0
public static class Demo2{ public static void main(String [] args){
SellTicketSystem s1 = new SellTicketSystem();
SellTicketSystem s2 = new SellTicketSystem();
s1.setName("111");
s2.setName("2222222222");
//System.out.println("sdsd");
s1.start();
s2.start();
}
}
static class SellTicketSystem extends Thread{
private static int mutex = 1;
private static String name = "2222222222";//另一个线程先开始
private boolean _wait(){
//确保上一次另一个线程拿到了资源
if(mutex==1 && !name.equals(this.getName())){
name = this.getName();
mutex--;
return true;
}else{
return false;
}
}
private void _signal(){
if(mutex==0 && ticket>0){
mutex++;
}
}
private static int ticket=20;
public void run(){
while(ticket>0){
if(ticket>0){
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
if(_wait()){
System.out.println(this.getName()+"卖到第"+ticket--+"张");
_signal();
}
}
}
}}
额,好像会产生死锁,等会我再研究下
http://blog.csdn.net/shijinupc/article/details/7250407这个多线程的例子非常经典,把这个例子搞懂,再能根据不同情况重写一个例子,多线程的基本使用就没问题了。
这篇文章能够解决你的问题