有两个问题请教大虾们:
1.synchronize关键字锁定某个对象,假如线程A锁定,那么线程A在解锁后,是不是马上另一个该对象锁池中的线程B马上开始执行,还是继续执行完线程A的其他代码?2.虚拟机对多线程的主动调度(并不是调用sleep,yield,join方法),也就是虚拟机对A线程执行一段时间后,主动让线程B执行一会,这不是存在很大的偶然性吗?在实际的编程肯定有这种影响吧,理解不是很深刻。
1.synchronize关键字锁定某个对象,假如线程A锁定,那么线程A在解锁后,是不是马上另一个该对象锁池中的线程B马上开始执行,还是继续执行完线程A的其他代码?2.虚拟机对多线程的主动调度(并不是调用sleep,yield,join方法),也就是虚拟机对A线程执行一段时间后,主动让线程B执行一会,这不是存在很大的偶然性吗?在实际的编程肯定有这种影响吧,理解不是很深刻。
效率低啊!
2 可能不同系统会不一样,NT系统上某个线程运行超过一定的时间片段后会强制切换给别的线程
2.线程调度并不是一个线程做完或者做一定量才切换到另一个线程
线程是微秒级切换的,是每一个微妙都有不同的进程/线程在获得CPU时间片,区别在于高优先级的线程有机会获得更多次的时间片而已
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赋的值
}
}
1.该线程获得了它执行所必须的资源
2,获得了CPU的执行时间
问题一:线程A解锁释放资源后,在等待队列中的线程B会马上得到该资源,但是得到了该资源后线程B不是马上就可以执行了,线程得到资源与线程执行是两码事,因为它还要有CPU的执行时间。所以线程B虽然得到了线程A释放的资源,但是这个时候还要看系统把CPU的时间篇分配给了哪个线程,如果是给了A,那么A继续执行,B暂停(虽然它有资源),反之
问题二:系统分配给各个线程的CPU执行时间确实存在很大的偶然性,这其实就是操作系统中的CPU的调度问题,具体要看系统是采用的哪个CPU调度算法(见计算机操作系统),所以在多线程的程序中,由于不能把握好系统分给各个线程的CPU时间,常常会出现一些莫名其妙的输出结果。