computeras13 Δημοσ. 8 Μαΐου 2011 Δημοσ. 8 Μαΐου 2011 Καλησπέρα σε όλους. Έχω φτιάξει ένα "framework" σε java το οποίο έχει σκοπό να προσομοιώσει έναν διαγωνισμό ναυμαχίας. Κάθε παίχτης λοιπόν θα φτιάχνει ένα δικό του bot κάνοντας implement ένα interface με όλες τις απαραίτητες μεθόδους που θα πρέπει να υλοποιήσει. Έπειτα αφού μαζευτούν όλα τα bots θα τρέχει ο διαγωνισμός καλώντας αντίστοιχα τις μεθόδους που πρέπει. Αποφάσισα λοιπόν να το γράψω ξανά χρησιμοποιώντας threads ώστε να μπορέσω να ορίσω και κάποιους περιορισμούς στον χρόνο εκτέλεσης των μεθόδων που θα καλώ (αυτές που έχουν φτιάξει οι παίχτες) καθώς και για άλλους λόγους. Έχω όμως το εξής πρόβλημα: όταν πάω να τρέξω μια function πρέπει απαραιτήτως να περάσω final ορίσματα. Έλα όμως που δεν θέλω γιατί οι functions αυτές υποτίθεται οτι είτε θα μου αλλάζουν τις παραμέτρους που δίνω είτε γενικώς θέλω κάτι να μου επιστρέφουν. Θα μπορούσα βέβαια να ελέγξω το θέμα τις επιστροφής μετατρέποντας το interface σε abstract και να καλείται στο τέλος κάθε function η super για να κάνει ότι θέλω εγώ. Το πρόβλημά μου όμως κυρίως είναι πως θα καταφέρω να περάσω μια παράμετρο η οποία θα αλλάξει τιμή ή γενικώς δεν θέλω να είναι final; ΥΓ: Αν χρειαστεί παράδειγμα κώδικα θα το προσθέσω αργότερα μιας και είμαι εκτός σπιτιού αυτή τη στιγμή.
computeras13 Δημοσ. 9 Μαΐου 2011 Μέλος Δημοσ. 9 Μαΐου 2011 Παραθέτω snippets. Τελικά έκανα abstract την BattleshipPlayer. > public abstract class BattleshipPlayer { // Εδώ υπάρχει περισσότερος κώδικας /** * This method is being called when you sould place your ships in the board * @param ships an ArrayList with all the ships you have to place */ public abstract void placeShips(ArrayList ships); // Εδώ υπάρχει περισσότερος κώδικας } Και εδώ είναι οι κλήσεις που θέλω να κάνω σε childs αυτής της κλάσης. > // Εδώ υπάρχει περισσότερος κώδικας try { Thread thread = new Thread(new Runnable() { @Override public void run() { player2.placeShips(ships.get(player1)); } }); thread.start(); thread.join(allowedTimeForFunction); } catch (Exception ex) { return declareWinner(player1); } // Εδώ υπάρχει περισσότερος κώδικας
computeras13 Δημοσ. 10 Μαΐου 2011 Μέλος Δημοσ. 10 Μαΐου 2011 Κανείς ρε παιδιά δεν ξέρει κάποιον τρόπο να το ξεπεράσω αυτό; Τουλάχιστον κάποια ιδέα για να το παρακάμψω; Έστω και αν περιλαμβάνει αλλαγές στην τρέχουσα δομή που ανέφερα.
παπι Δημοσ. 10 Μαΐου 2011 Δημοσ. 10 Μαΐου 2011 Δεν ξερω πως δουλευει η java τα threads, αλλα θεωρητικα δεν γινεται δυο thread να επεξεργαζονται ενα object ταυτοχρονα χωρις να χρησιμοποιουν monitor BTW με ενα search που εκανα, ειδα οτι για να περασεις παραμετρους μεσα σε ενα thread πρεπει να κανεις -ενα object πανω στο runnable/thread με constructor που θα περναι τις παραμετρους -να φτιαξεις ενα object τυπου Thread με παραμετρο το παραπανω object που θα εχει παραμτρους αυτους που θελεις -start > class MyThread imps Thread { object obj; MyThread(object param) { obj = param; } void run() { do somthing with obj } } .... object obj;... Thread th = new Thread(new MyThread(obj)); th.start()
computeras13 Δημοσ. 11 Μαΐου 2011 Μέλος Δημοσ. 11 Μαΐου 2011 Για τον συγχρονισμό που λες θα του ρίξω μια ματιά (όσο πιο σύντομα μπορώ γιατί αύριο παρουσιάζω πτυχιακή και θα έχω γενικώς και τρεχάματα για να κάνω και τα χαρτιά για ορκομωσία). Όσον αφορά το δεύτερο που λες, ναι έχεις δίκαιο, μπορείς όμως να το κάνεις και όπως το κάνω εγώ στο δεύτερο snippet ώστε να τρέξεις μια οποιαδήποτε μέθοδο σαν thread κάνοντας μια anonymous class στην ουσία.
warchief Δημοσ. 13 Μαΐου 2011 Δημοσ. 13 Μαΐου 2011 όταν πάω να τρέξω μια function πρέπει απαραιτήτως να περάσω final ορίσματα. Έλα όμως που δεν θέλω γιατί οι functions αυτές υποτίθεται οτι είτε θα μου αλλάζουν τις παραμέτρους που δίνω είτε γενικώς θέλω κάτι να μου επιστρέφουν. Αυτο ειναι εξ ορισμού πρόβλημα σχεδιαστικό, πως ειναι δυνατόν να έχεις ταυτόχρονα απαίτηση τα ορίσματα να ειναι final, αλλα και να τα τροποποιεί η μέθοδος που τα δέχεται? Ή το ένα θα γίνει ή το άλλο. Εχω διαβάσει το πρώτο σου post αρκετές φορές και ακόμα δεν έχω καταλάβει ποιο ειναι ακριβώς το πρόβλημα (ιδιαίτερα όταν κοιτάω τα code snippets του 2ου post). Τέλος > thread.start(); thread.join(allowedTimeForFunction); Αυτό που προσπαθείς να πετύχεις (αν εχω καταλαβει καλά) θα σου δημιουργήσει περισσότερα προβλήματα απο όσα περιμένεις. Απο το Java API σχετικά με Thread::join(millis) Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever. Στην περίπτωση σου η κληση στην join θα μπλοκάρει το main thread για allowedTimeForFunction millisec και μετα ο κωδικας του main thread θα συνεχίσει, όπως και η εκτέλεση του thread που δημιούργησες προηγουμένως.
computeras13 Δημοσ. 13 Μαΐου 2011 Μέλος Δημοσ. 13 Μαΐου 2011 Αν ισχύει το τελευταίο που λες τότε ναι είναι λάθος η γραμμή αυτή. Θα ξαναγράψω τι θέλω μήπως και αυτή τη φορά το θέσω καλύτερα. Λοιπόν έχω μια κλάση ενός αντικειμένου δικού μου με διάφορες μεθόδους του οι οποίες είτε επιστρέφουν κάποια πράγματα είτε αλλάζουν τα αντικείμενα που περνάνε σαν αναφορά. Από το main thread θέλω να καλώ τις μεθόδους από την προηγούμενη κλάση θέτοντας ένα όριο στον χρόνο εκτέλεσής τους. Ψάχνω λοιπόν ένα τρόπο να κάνω αυτό. Το αν θα γίνει μέσω threads ή όχι δεν είναι βασική ανάγκη. Καμιά ιδέα;
warchief Δημοσ. 13 Μαΐου 2011 Δημοσ. 13 Μαΐου 2011 Από το main thread θέλω να καλώ τις μεθόδους από την προηγούμενη κλάση θέτοντας ένα όριο στον χρόνο εκτέλεσής τους. Ψάχνω λοιπόν ένα τρόπο να κάνω αυτό. Το αν θα γίνει μέσω threads ή όχι δεν είναι βασική ανάγκη. Θα μπορούσες να θέσεις ένα όριο στον χρόνο εκτέλεσης ενος "thread" (είναι ευκολότερο να σκοτώσεις ένα process παρά ένα thread) , αλλά αυτή η λογική έχει ένα συγκεκριμένο μειονέκτημα. Την στιγμή που σκοτώνεις το thread/process δεν μπορείς να είσαι σίγουρος ποιες μεταβλητές έχει κάνει modify και τι όχι. Στην περίπτωση σου, ίσως θα έπρεπε να σκεφτείς έναν διαφορετικό σχεδιασμό: > public abstract void placeShips(ArrayList ships); o implementor της placeShips, όταν την υλοποιεί λογικά χρησιμοποιεί κάποιες άλλες κλήσεις του API σου ας πούμε > void do_foo(); void do_bar(); void do_zoo(); Τις παραπάνω μεθόδους τις υλοποιείς εσύ και τις δίνεις έτοιμες να τις χρησιμοποιήσει ο κάθε παίκτης. Για κάθε μια απο αυτές τις κλήσεις θα μπορούσες να εισάγεις ένα 'κόστος' κλήσης ας πούμε 1 credit. Με αυτη την λογική η κλήση στην do_foo κοστίζει ένα credit, στην do_bar επίσης ενα, κ.ο.κ. Κάθε φορά που ο implemetor καλεί μια εκ των do_foo, do_bar, do_zoo χάνει αντίστοιχα credits απο το 'πορτοφολι΄του. Θα μπορούσες λοιπόν αργότερα να δίνεις X (πχ 5) credits σε κάθε παίκτη της ναυμαχίας. Οταν ο παίκτης φτάσει το credit limit του απλά δεν τον αφήνεις να παίξει άλλο (πχ η κλήση στην do_foo απλά επιστρέφει, κτλπ). μέχρι η placeShips να επιστρέψει και το thread να κάνει exit όμορφα και ωραία.
computeras13 Δημοσ. 13 Μαΐου 2011 Μέλος Δημοσ. 13 Μαΐου 2011 Ο implementor δεν θα καλεί απαραίτητα κάποιες από τις δικές μου μεθόδους (μερικές φορές δεν είναι αναγκαίο). Ο λόγος που θέλω να το κάνω αυτό είναι για να περιορίσω τον χρόνο που δίνεται στον κάθε παίχτη, ώστε (πέραν της αντιμετώπισης του λάθους κώδικα) να υπάρχει και ο χρόνος εκτέλεσης σαν ένα κομμάτι του διαγωνισμού.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.