si può sospendere l'esecuzione di un codice in attesa di un evento senza usare i thread?![]()
si può sospendere l'esecuzione di un codice in attesa di un evento senza usare i thread?![]()
Si può usare la condition-queue intrinseca di un oggetto, ovvero i wait() e notify() (e notifyAll()). Oppure le classi per la gestione della concorrenza ad "alto livello" nel package java.util.concurrent (e sotto package).Originariamente inviato da killerbomb
si può sospendere l'esecuzione di un codice in attesa di un evento senza usare i thread?![]()
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
io ho fatto cosi ma non funziona:Originariamente inviato da andbin
Si può usare la condition-queue intrinseca di un oggetto, ovvero i wait() e notify() (e notifyAll()). Oppure le classi per la gestione della concorrenza ad "alto livello" nel package java.util.concurrent (e sotto package).
e questa e la classe dove c'è il notify():codice:public class Finestra extends JFrame implements MouseListener { public int x, y; public gestione ge=new gestione(); private JLabel la = new JLabel("clicca sullo schermo!",JLabel.RIGHT); BufferedImage image; public Finestra() { try { //codice finestra } catch (AWTException exception){} } public void paint(Graphics g){ g.drawImage(image,0,0,null); } public void newimg(){ try { Robot robot = new Robot(); robot.delay(2000); image = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); repaint(); } catch (AWTException exception){} } public void newi(){ new Finestra(); } public void cl(){ try{ setExtendedState(ICONIFIED); //codice cl() } } catch (AWTException e) { e.printStackTrace(); } } public void ins(int cx,int cy,int time){ try{ System.out.println("appostu"); int xx=cx; int yy=cy; ge.inserisci(new click(time,xx,yy)); } catch (Exception e) { e.printStackTrace(); System.out.println("errore ins()"); } } public void mousePressed(MouseEvent e) { x = e.getX(); y = e.getY(); enter es=new enter(); try{ wait(); } catch(Exception E) {System.out.println("errore wait");} ins(x,y,es.tim); } public void sta(){ ge.stampa(); } public void nuovaf(){ new Finestra(); } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } }
codice:public class enter extends JFrame {JLabel la; TextField t; int tim; public enter() { setLayout(new GridLayout(3,1)); setSize(300,300); setTitle("setup tempo"); la= new JLabel("inserisci l'attesa prima del clik"); add(la); t=new TextField("millisecondi",10); add(t); Button b=new Button("ok"); Ascoltob a1= new Ascoltob(); b.addActionListener(a1); add(b); setVisible(true); } private class Ascoltob implements ActionListener { public void actionPerformed(ActionEvent E) { tim=Integer.parseInt(t.getText()); notify(); setVisible(false); } } }
Non ho letto tutto ma ho visto subito che è sbagliato (molto) concettualmente.Originariamente inviato da killerbomb
io ho fatto cosi ma non funziona:
Vorresti fare una wait() nel mousePressed(). Questo è profondamente sbagliato. I metodi dei listener vengono invocati nel contesto del EDT, il event dispatch thread. Il thread che si occupa, tra le altre cose, di disegnare la interfaccia utente e di dispacciare gli eventi ai listener.
Questo thread non lo devi mai bloccare più di tanto. Altrimenti la tua interfaccia utente è "congelata". Ripeto: nel contesto del EDT non si dovrebbero mai fare sleep(), wait() o altro che possa bloccare, potenzialmente, per troppo tempo questo thread.
A parte questo, dal punto di vista tecnico, il wait() deve essere invocato su un oggetto di cui il thread corrente possiede il "lock". E nel tuo codice non vedo alcuna acquisizione di un lock.
E a parte questo l'uso di wait() generalmente va fatto dentro un ciclo while che testa una "precondition" che è quella che determina la condizione di wait o no.
Immagina una "coda" tale per cui chi legge, se non ci sono elementi, si blocca fino all'arrivo di almeno 1 elemento. La precondizione è appunto "se non ci sono elementi" allora metti in attesa. Ma va fatto in loop per questioni abbastanza fini che ora non sto a spiegarti e che centrano anche con il fatto che in base alla JVM ci potrebbero anche essere dei notify "spurii".
Non vorrei sembrarti scortese ... ci mancherebbe, ma queste cose, a questo livello, vanno studiate bene perché altrimenti rischi di fare cose profondamente sbagliate concettualmente, cose che magari funzionano 9 volte si e 1 no (per botta di sfortuna), o addirittura che non funzionano proprio mai o che non funzionano come vorresti.
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Prova ad applicare il design pattern Observer. Se ti può essere utile dai un occhio qui per un semplice esempio di applicazione di questo pattern, noto anche come Publish-Subscribe e tipicamente usato per le applicazioni GUI. Nel tuo caso l'oggetto che 'rimane in attesa' di un evento implementa l'interfaccia java.util.Observer, mentre l'oggetto che genera l'evento estende java.util.Observable.Originariamente inviato da killerbomb
si può sospendere l'esecuzione di un codice in attesa di un evento senza usare i thread?![]()
Io per "sospendere" come ha detto lui all'inizio intenderei proprio la sospensione del thread. E per questo l'Observer non centra/serve a nulla.Originariamente inviato da Santinizer
Prova ad applicare il design pattern Observer.
Viste le premesse iniziali, visto che il codice postato gestisce una interfaccia utente e visto quanto ho risposto prima .... direi che la questione dovrebbe essere chiarita bene.
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Credo che per quello che vuole realizzare killerbomb, al di la della soluzione proposta successivamente da lui stesso, potrebbe essere utile dare un occhio al design pattern Observer, che consente di evitare l'uso di wait()/notify()/notifyAll() con tutti i rischi annessi e sicuramente rappresenta una soluzione più elegante.Originariamente inviato da andbin
Io per "sospendere" come ha detto lui all'inizio intenderei proprio la sospensione del thread. E per questo l'Observer non centra/serve a nulla.
Viste le premesse iniziali, visto che il codice postato gestisce una interfaccia utente e visto quanto ho risposto prima .... direi che la questione dovrebbe essere chiarita bene.
Ciao