在线程的run()方法中的while循环没有停止
这涉及到浮点型精度不准确问题,建议你把两边都转成int类型,进行比较
不可能所有的线程都满足energyBoxes[from] < amount,不然总能量会小于初始能量
是的,但最好用小一点的对象,减少系统开销
final修饰的数组只是说你的数组不能再指向其他数组对象, 但它指向的数组的内容是可以变的!
而final修饰的锁对象为了保证多线程进行过程中的安全
final修饰的数组只是说你的数组不能再指向其他数组对象, 但它指向的数组的内容是可以变的!
而final修饰的锁对象为了保证多线程进行过程中的安全
其他线程处于就绪队列,等待抢占资源,而wait是进入等待队列不能抢占资源,如果没有wait,那么条件不足的线程不进入等待队列而是进入就绪队列,这样的话该线程就有可能再一次进行同步锁进入退出的操作,这就是所谓的加大开销。
声明:解释转自 sxian_wang 的回答
先明白两个概念:锁池和等待池。synchronized是锁池,wait、notify、notifyAll是等待池。等待池的对象是不会竞争锁的,当notifyAll后,等待池中的线程会被唤醒进入到该线程的锁池中重新竞争对象锁,重新获得锁后的对象会从wait后继续执行代码,其他对象会被阻塞,而不是wait。被阻塞的对象会等待下一次被唤醒(notify、notifyAll)。另外,notify不是线程安全的,notifyAll才是。
10000 -> 9999.999999999999 这是浮点数精度导致的问题。这段代码我看了,是正确的
软件要同时完成两个任务的时候使用
我认为是 for循环100次 的 Thread t=new Thread(task,"TransferThread_"+i);t.start(); 是多线程
放在while中,等待的时间是当条件不满足时,不执行。放在if中只能执行一次。而前面的代码也是用while获取的。
既然理解成线程会阻塞,不会执行。当其他线程NotifyAll的时候,如果他获取资源,又会发生阻塞。那么这个线程会一直运行下去,不会消亡?(while条件一直成立)
这个设置了,这是我的代码,我跟视频上不完全一样,一个是测试,一个thread,谢谢了
package project_thread; public class EnergyThread extends Thread { private final double[] energy_box; private double energy_max; private Object lock=new Object(); @Override public void run() { // TODO Auto-generated method stub while (true) { int from=(int) (Math.random()*getlength()); int to =(int) (Math.random()*getlength()); double energy=Math.random()*energy_max; int time=(int) (Math.random()*50); energy_tansform(from, to, energy); try { sleep(time); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public EnergyThread(double energy_initial,int n) { // TODO Auto-generated constructor stub this.energy_box=new double[n]; this.energy_max=energy_initial; for (int i = 0; i < n; i++) { energy_box[i]=energy_initial; } } public int getenergy_total() { double total=0; for (double d : energy_box) { total+=d; } return (int)total; } public void energy_tansform(int from,int to ,double energy) { synchronized (lock) { if(energy_box[from]<energy){ try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } energy_box[from]-=energy; energy_box[to]+=energy; System.out.println(getName()+":energy_box["+from+"]向energy_box["+to+"]转移"+energy+"energy_total="+getenergy_total()); lock.notifyAll(); } } public int getlength() { return energy_box.length; } }
package project_thread; public class ThreadTest { public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0;i<100;i++){ Thread thread=new EnergyThread(1000,100); thread.start(); } } }
是精度的问题,如果按照老师精确到两位小数则没有问题。
我感觉是一样的,都是占着锅里的,渴望对方碗里的,还死不想让,结果导致被占着的厕所永远被这两个人占领,其他人都无法正常使用。除非关闭停止运行程序,大家都去睡觉,不然这两个线程将永远处于死锁状态。而且第二天还是有可能再次出现这种情况的,不过概率很小而已。
就等于是你在等待办业务,在办业务的这个办公室只能有一个人进去,lockObj对象就等于这个办公室,外面等待的人就是这个办公室所拥有的wait set,当一个人办完业务时,办公室会通知所有等待的人说可以进去了,那么这外面等待的所有的人就都同时获得了平等的竞争进入办公室的权力。
Lock lock = new ReentrantLock()
lock.lock()
lock.unlock()
我得到最后的答案是因为每次都执行一次notify;所以即使他wait()了释放了锁,由于他上一次执行了 notify()了,所以就已经叫醒了另外的线程,注意这个notify和wait()不是在同一次过程中的。
这个要分情况的。如果你是用的实现Runnable类的方式的话可以直接使用this,而如果是使用继承Thread的方式时就不要使用this,因为此时this指向不同对象,这样每个线程都拥有自己的锁,无法实现同步
不太懂你的问题