我觉得,把票数定义在线程里是不对的,这样子不就是各个线程启动后,处理的都是各自的票数吗? 改成下面这样,放在主线程里定义,就不会出错。 class MyThread extends Thread { private int num; public MyThread(int num){this.num=num;} @Override public void run() { while(num>0)
} } public class Test2 { public static void main(String[] args) { final int num=100; MyThread my1 = new MyThread(num); MyThread my2 = new MyThread(num); my1.setName("窗口1"); my2.setName("窗口2"); my1.start(); my2.start(); } }
原因:
1、单核cpu执行多线程实际上是来回切换执行线程(1线程执行了一次,切换到2线程执行,甚至于连续执行某个线程),由于是单核,所以第二次执行的线程必然等到第一次完成后才有机会执行(必然出现时间差)。
2、多核cpu,cpu1执行的时候,cpu2同样可以执行,那么这时就可能出现同时操作tickets的情况,就是你打印出来的“窗口2正在出售第100张票”说的不对望指正,个人对cpu如何执行指令没有研究过。
改成下面这样,放在主线程里定义,就不会出错。
class MyThread extends Thread {
private int num;
public MyThread(int num){this.num=num;}
@Override
public void run() {
while(num>0)
System.out.println(getName() + "正在出售第" + (num--) + "张票");
}
}
public class Test2 {
public static void main(String[] args) {
final int num=100;
MyThread my1 = new MyThread(num);
MyThread my2 = new MyThread(num);
my1.setName("窗口1");
my2.setName("窗口2");
my1.start();
my2.start(); }
}
你只有两个线程,运行哪一个线程是JVM说了算的,两个线程是交替运行的,之所以看起来有的时候没有问题是因为你的线程的数量太少了,如果你的线程多一些,一定会不按照顺序依次执行的现象出现第二段代码:
你在每一个SellTicket里面都有100张票,相当于每个窗口都给了100张票,窗口间谁先卖谁后卖会乱,但是每个窗口自己卖票的顺序一定是从100到1递减的,所以没有你认为的混乱的问题第一个回复:
你的理解是错误的,JVM相当于是一个虚拟机,JVM里面运行的代码和计算机有几个核是没有关系的
public class Test extends Thread{
private static int tickets = 100;
private String name;
public Test(String name){
this.name=name;
}
private static synchronized int sellOneTicket(){
return tickets--;
}
private static boolean haveTicket(){
boolean b = false;
if(tickets>0){
b=true;
}
return b;
}
@Override
public void run() {
while(Test.haveTicket()){
System.out.println(this.name + "正在出售第" + sellOneTicket() + "张票");
}
} //Main方法
public static void main(String[] args){
Test t1 = new Test("窗口1");
Test t2 = new Test("窗口2");
t1.start();
t2.start();
}
}
运行结果:
窗口1正在出售第100张票
窗口1正在出售第99张票
窗口1正在出售第98张票
窗口1正在出售第97张票
窗口1正在出售第95张票
窗口2正在出售第96张票
窗口1正在出售第94张票
窗口2正在出售第93张票
窗口1正在出售第92张票
窗口2正在出售第91张票
窗口1正在出售第90张票
窗口2正在出售第89张票
窗口1正在出售第88张票
窗口2正在出售第87张票
窗口1正在出售第86张票
窗口2正在出售第85张票
窗口1正在出售第84张票
窗口2正在出售第83张票本人I7处理器 4核。
对cpu来说就是把b的值 取出来——然后给a——把a存进去——把b-1——再把b存进去。没记错应该是分这几步。中间没有锁定之类的是随时都有可能断掉的。
private static BlockingQueue<对象> queue = new ArrayBlockingQueue<对象>(100);