আমি কীভাবে আমার অ্যারেলিস্ট থ্রেড-নিরাপদ করব? জাভা সমস্যা অন্য পদ্ধতির?


90

আমার কাছে একটি অ্যারেলিস্ট রয়েছে যা আমি রেসকার অবজেক্টগুলি ধরে রাখতে ব্যবহার করতে চাই যা থ্রেড ক্লাসটি সম্পাদন শেষ হওয়ার সাথে সাথে প্রসারিত হয়। রেস নামে একটি শ্রেণি একটি কলব্যাক পদ্ধতি ব্যবহার করে এই অ্যারেলিস্টটি পরিচালনা করে যা রেসিকার অবজেক্টটি সম্পাদন শেষ হলে কল করে। অ্যাডফিনিশার (রেসকার ফিনিশার) কলব্যাক পদ্ধতিটি অ্যারেলিস্টে রেসকার আইটেম যুক্ত করে। এটি থ্রেডগুলি কার্যকর করা শেষ করার আদেশ দেয়।

আমি জানি যে অ্যারেলিস্টটি সিঙ্ক্রোনাইজ করা হয়নি এবং এটি থ্রেড-নিরাপদ নয়। আমি একটি নতুন অ্যারেলিস্টে পাস করে এবং ফিরে সংগ্রহটি একটি অ্যারেলিস্টে বরাদ্দ করে আমি কালেকশন.সিনক্রোনাইজড কালেকশন (সি সংগ্রহ) পদ্ধতিটি ব্যবহার করার চেষ্টা করেছি। তবে এটি আমাকে একটি সংকলক ত্রুটি দেয়:

Race.java:41: incompatible types
found   : java.util.Collection
required: java.util.ArrayList
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));

এখানে প্রাসঙ্গিক কোড:

public class Race implements RaceListener {
    private Thread[] racers;
    private ArrayList finishingOrder;

    //Make an ArrayList to hold RaceCar objects to determine winners
    finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));

    //Fill array with RaceCar objects
    for(int i=0; i<numberOfRaceCars; i++) {
    racers[i] = new RaceCar(laps, inputs[i]);

        //Add this as a RaceListener to each RaceCar
        ((RaceCar) racers[i]).addRaceListener(this);
    }

    //Implement the one method in the RaceListener interface
    public void addFinisher(RaceCar finisher) {
        finishingOrder.add(finisher);
    }

আমার যা জানা দরকার তা হল, আমি কি একটি সঠিক পদ্ধতি ব্যবহার করছি এবং যদি তা না হয় তবে আমার কোড থ্রেড-নিরাপদ করতে আমার কী ব্যবহার করা উচিত? সাহায্যের জন্য ধন্যবাদ!


4
(দ্রষ্টব্য, Listইন্টারফেসটি মাল্টিথ্রেডিংয়ে খুব কার্যকর হতে যথেষ্ট পর্যাপ্ত নয়))
টম হাটিন -

4
আমি কেবল এটি উল্লেখ Collections.synchronizedList()করতে চাই , ছাড়া , আমাদের এখানে একটি সত্যিকারের রেসের অবস্থা থাকতে হবে: পি
ডিলান ওয়াটসন

এই লিঙ্কটি দেখুন প্রোগ্রামারজোডোজো
জাভা

উত্তর:


147

ব্যবহার Collections.synchronizedList()

প্রাক্তন:

Collections.synchronizedList(new ArrayList<YourClassNameHere>())

4
ধন্যবাদ! আমি নিশ্চিত না কেন আমি কেন কেবল কোনও ভেক্টর ব্যবহার করতে ভেবে দেখিনি যেহেতু কোথাও সেগুলি সিঙ্ক্রোনাইজ করা হয়েছিল তা মনে পড়ে।
এরিকো


4
যদিও ভেক্টরটি বেশ পুরানো এবং সংগ্রহে-সমর্থনের অভাব রয়েছে, এটি অবহেলা করা হয়নি। অন্যান্য লোকদের মতো এখানে কালেকশন.সিনক্রোনাইজডলিস্ট () ব্যবহার করা ভাল।
আস্তুরিও

14
মন্তব্যের জন্য -1। ভেক্টর অবহেলিত নয় এবং কীভাবে এটি সংগ্রহের সমর্থন করে না? এটি তালিকা কার্যকর করে। ভেক্টরের জাভাডোকটি স্পষ্টভাবে বলেছে: "জাভা 2 প্ল্যাটফর্মের ভি 1.2 হিসাবে, এই শ্রেণিটি তালিকা ইন্টারফেসটি প্রয়োগ করার জন্য পুনঃনির্মাণ করা হয়েছিল, এটি জাভা সংগ্রহ সংগ্রহ ফ্রেমের একটি সদস্য হিসাবে তৈরি করেছিল। নতুন সংগ্রহ বাস্তবায়নের বিপরীতে, ভেক্টর সংহত হয়েছে।" ভেক্টর (সিঙ্ক্রোনাইজেশন এড়ানো, বাস্তবায়ন পরিবর্তন করা) এর সঠিক কারণগুলি থাকতে পারে, তবে "অপ্রচলিত" বা "আধুনিক নয়" হওয়া তাদের মধ্যে একটি নয়।
বোকা 4

4
নীচের পদ্ধতিগুলি ব্যবহার করুন: সংগ্রহ.সিনক্রোনাইজড তালিকা (তালিকা); সংগ্রহ.সিনক্রোনাইজড সেট (সেট); সংগ্রহ.সিনক্রোনাইজড ম্যাপ (মানচিত্র); উপরের পদ্ধতিগুলি সংগ্রহকে প্যারামিটার হিসাবে গ্রহণ করে এবং একই ধরণের সংগ্রহটি সিঙ্ক্রোনাইজ করা এবং থ্রেড নিরাপদ করে দেয়।
সমীর কাজী

35

পরিবর্তন

private ArrayList finishingOrder;

//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars)

প্রতি

private List finishingOrder;

//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedList(new ArrayList(numberOfRaceCars)

তালিকাটি অ্যারেলিস্টের একটি সুপারটাইপ যা আপনাকে এটি নির্দিষ্ট করতে হবে।

অন্যথায়, আপনি যা করছেন তা ভাল মনে হচ্ছে। অন্য বিকল্পটি হ'ল আপনি ভেক্টরটি ব্যবহার করতে পারেন যা সিঙ্ক্রোনাইজড, তবে সম্ভবত এটিই আমি করতাম।


4
অথবা Listসম্ভবত আরও দরকারী হবে। বা List<RaceCar>
টম হাটিন -

ভাল কথা, এটিকে বেসরকারী তালিকা তৈরি করুন FinningOrder = Collections.synchronizedList (...)
শ্রদ্ধেয় গঞ্জো

আমি এটি চেষ্টা করেছিলাম এবং সংকলক এখন আমাকে সংগ্রহেরে অ্যারেলিস্ট পদ্ধতিগুলি কল করার বিষয়ে অভিযোগ করছে: //Print out winner System.out.println("The Winner is " + ((RaceCar) finishingOrder.get(0)).toString() + "!"); এটি বলছে যে (0) পদ্ধতিটি পাওয়া যায় নি। ভাবনা?
এরিকো

আমার মন্তব্য মুছে ফেলা এবং পুনরায় যুক্ত করার জন্য দুঃখিত। আমি ব্যাকটিক্স ব্যবহার করে হাইলাইট করার কাজ করার চেষ্টা করছিলাম। আমি এই ধরণের স্টাফ সম্পর্কে ওসিডি পাই।
এরিকসো

না, এটি কাজ করে না। এটি সংগ্রহকে কোনও তালিকায় ফেলে দেবে না: রেস.জভা ৪৪:১৫ অসামঞ্জস্যপূর্ণ প্রকারগুলি পাওয়া গেছে: java.util. সংগ্রহ প্রয়োজন: java.util.List সমাপ্তি অর্ডার = সংগ্রহসমূহ ynসিনক্রোনাইজড কালেকশন (নতুন অ্যারেলিস্ট (সংখ্যাআফ্রেসেস));
এরিকো

11

CopyOnWriteArrayList

CopyOnWriteArrayListক্লাস ব্যবহার করুন । এটি থ্রেড নিরাপদ সংস্করণ ArrayList


4
এই ক্লাসটি বিবেচনা করার সময় দুবার চিন্তা করুন। ক্লাস ডকটি উদ্ধৃত করার জন্য: "এটি সাধারণত খুব ব্যয়বহুল, তবে ট্র্যাভার্সাল অপারেশনগুলি বিভাজনকে অনেক বেশি ছাড়িয়ে যায় এবং বিকল্পগুলির তুলনায় আরও কার্যকর হতে পারে এবং যখন আপনি ট্র্যাভারসালগুলি সিঙ্ক্রোনাইজ করতে বা না করতে চান বা করতে চান না তখন কার্যকর হয়, তবুও সমকালীন থ্রেডগুলির মধ্যে হস্তক্ষেপ অবরুদ্ধ করতে হবে ” এছাড়াও, দেখতে CopyOnWriteArrayList এবং synchronizedList মধ্যে পার্থক্য
বেসিল Bourque

আপনি যখন তালিকাটি খুব কমই সংশোধন করেন তবে এই উপাদানগুলি প্রায়শই উপাদানগুলির মাধ্যমে পুনরাবৃত্তি হয় play যেমন আপনার যখন শ্রোতার সেট থাকে a আপনি সেগুলি নিবন্ধ করুন এবং তারপরে আপনি প্রচুর পরিমাণে পুনরাবৃত্তি করুন ..., যদি আপনার স্পষ্টভাবে তালিকা ইন্টারফেসের প্রয়োজন না হয় তবে ConcurrentLinkedQueue
সাম্প্রতিক

7

আপনি হয়ত ভুল পদ্ধতির ব্যবহার করছেন। অন্য কার-সিমুলেশন থ্রেডের আগে একটি গাড়ি শেষ করে এমন এক থ্রেডের অর্থ এই নয় যে প্রথম থ্রেডটি সিমুলেটেড রেসটি জিততে হবে।

এটি আপনার আবেদনের উপর অনেক বেশি নির্ভর করে, তবে এমন এক থ্রেড থাকা ভাল যা দৌড় শেষ না হওয়া পর্যন্ত অল্প সময়ের ব্যবধানে সমস্ত গাড়ির স্থিতি গণনা করে। অথবা, আপনি যদি একাধিক থ্রেড ব্যবহার করতে পছন্দ করেন তবে প্রতিযোগিতাটি সম্পূর্ণ করতে আপনার প্রতিটি গাড়ি "নকল" সময় রেকর্ড করতে পারে এবং সবচেয়ে কম সময়ের সাথে বিজয়ীকে বেছে নিতে পারে choose


এটা একটা ভাল দিক. আমি জাভা শিখতে ব্যবহার করছি এমন একটি পাঠ্য থেকে এটি একটি অনুশীলন। মূল বিষয়টি কীভাবে থ্রেডগুলি ব্যবহার করতে হয় তা শিখতে হয়েছিল এবং আমি বিজয়ীদের লগ করার জন্য একটি মেকানিজম তৈরির ক্ষেত্রে সমস্যার মূল স্পেসিফিকেশনগুলি ছাড়িয়ে যাচ্ছি। আমি যদিও বিজয়ীদের পরিমাপ করতে টাইমার ব্যবহার করছি। তবে সত্যই, আমি মনে করি অনুশীলন থেকে আমার যা প্রয়োজন তা অর্জন করেছি।
এরিকো

5

আপনি এই জাতীয় পদ্ধতির synchronizedজন্য কীওয়ার্ডও ব্যবহার করতে পারেনaddFinisher

    //Implement the one method in the RaceListener interface
    public synchronized void addFinisher(RaceCar finisher) {
        finishingOrder.add(finisher);
    }

সুতরাং আপনি এই পদ্ধতিতে অ্যারেলিস্ট যুক্ত পদ্ধতি থ্রেড-নিরাপদ ব্যবহার করতে পারেন।


4
ভাল, তবে আপনি যদি দুটি পদ্ধতি পেয়ে থাকেন: অ্যাডফিনিশার এবং ডেলফিনিশার? উভয় পদ্ধতি থ্রেড-নিরাপদ তবে উভয় একই অ্যারেলিস্ট অ্যাক্সেস করার পরে আপনি এখনও সমস্যায় পড়তে পারেন।
ওমনি

4
@ ম্যাসি তারপরে আপনি যখনই কোনও উপায়ে final Objectঅ্যাক্সেস করবেন তখন প্রতিবার পরিবর্তে আপনি একটি সিঙ্ক্রোনাইজ করুন Collection
এমকিউচ

2

যখনই আপনি পিঁপড়া সংগ্রহের বস্তুর পিঁপড়া থ্রেড নিরাপদ সংস্করণ ব্যবহার করতে চান, java.util.concurrent। * প্যাকেজটির সহায়তা নিন। এটিতে আনইনক্রোনাইজড কালেকশন অবজেক্টগুলির প্রায় সমস্ত সমসাময়িক সংস্করণ রয়েছে। উদাহরণস্বরূপ: অ্যারেলিস্টের জন্য আপনার কাছে java.util.concurrent.CopyOnWriteArrayList রয়েছে

আপনি কালেকশন.সিনক্রোনাইজড কালেকশন (যে কোনও সংগ্রহের বস্তু) করতে পারেন তবে এই ক্লাসিকাল সিঙ্করটি মনে রাখবেন। কৌশল ব্যয়বহুল এবং ওভারহেড পারফরমেন্সের সাথে আসে। java.util.concurrent। * প্যাকেজটি কম ব্যয়বহুল এবং এর মতো প্রক্রিয়া ব্যবহার করে আরও ভাল পদ্ধতিতে কার্য সম্পাদন পরিচালনা করে

অনুলিপি-অনুলিপি, তুলনা-ও-সোয়াপ, লক, স্ন্যাপশট পুনরাবৃত্তি ইত্যাদি।

সুতরাং, java.util.concurrent * প্যাকেজ থেকে কিছু পছন্দ করুন


1

পরিবর্তে আপনি ভেক্টর হিসাবেও ব্যবহার করতে পারেন, কারণ ভেক্টরগুলি থ্রেড নিরাপদ এবং অ্যারেলিস্ট নয়। যদিও ভেক্টরগুলি পুরানো তবে তারা সহজেই আপনার উদ্দেশ্য সমাধান করতে পারে।

তবে আপনি আপনার অ্যারেলিস্টকে কোডটি দেওয়া কোডের মতো সিঙ্ক্রোনাইজ করতে পারেন:

Collections.synchronizedList(new ArrayList(numberOfRaceCars())); 

-1

আপনি অ্যারেলিস্ট থেকে ভেক্টর প্রকারে পরিবর্তন করতে পারেন, যেখানে প্রতিটি পদ্ধতি সিঙ্ক্রোনাইজ করা হয়।

private Vector finishingOrder;
//Make a Vector to hold RaceCar objects to determine winners
finishingOrder = new Vector(numberOfRaceCars);

4
যদি আপনি অন্য সংগ্রহটি ব্যবহার করার পরামর্শ দিতে যাচ্ছেন তবে সম্ভবত ভেক্টর একটি খারাপ পছন্দ। এটি একটি উত্তরাধিকার সংগ্রহ যা নতুন জাভা সংগ্রহ ফ্রেমওয়ার্কের নকশায় পুনঃনির্মাণ করা হয়েছিল। আমি নিশ্চিত যে java.until.concurrent প্যাকেজে আরও ভাল পছন্দ রয়েছে।
এডউইন ডালরজো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.