জাভাতে স্থানীয় ভেরিয়েবল থ্রেড কেন নিরাপদ


91

আমি জাভাতে মাল্টি-থ্রেডিং পড়ছিলাম এবং আমি এটি জুড়ে এসেছি

স্থানীয় ভেরিয়েবলগুলি জাভায় থ্রেড নিরাপদ।

সেই থেকে আমি ভাবছিলাম যে কীভাবে / কেন স্থানীয় ভেরিয়েবলগুলি থ্রেড নিরাপদ।

কেউ দয়া করে আমাকে জানাতে পারেন?


27
কারণ তারা স্ট্যাক বরাদ্দ করা হয়। এবং থ্রেডগুলি স্ট্যাক ভাগ করে না নি ... প্রতিটিটির জন্য এটির অনন্য ..
রোহিত জৈন

উত্তর:


103

আপনি যখন একটি থ্রেড তৈরি করবেন তখন এটির নিজস্ব স্ট্যাক তৈরি হবে। দুটি থ্রেডে দুটি স্ট্যাক থাকবে এবং একটি থ্রেড এর স্ট্যাকটি অন্য থ্রেডের সাথে ভাগ করে না।

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

ইউটিউবে স্ট্যানফোর্ডের অধ্যাপকের দুর্দান্ত বক্তৃতা রয়েছে যা আপনাকে এই ধারণাটি বুঝতে সহায়তা করতে পারে।


13
আমি দুঃখিত, আপনি ভুল, শুধুমাত্র আদিম স্থানীয় ভেরিয়েবলগুলি স্ট্যাকের মধ্যে সংরক্ষণ করা হয়। বাকি সমস্ত ভেরিয়েবল হিপ-এ সংরক্ষণ করা হয়। জাভা 7 পালানোর বিশ্লেষণ প্রবর্তন করেছে, যা কিছু বৈকল্পের জন্য এটি স্ট্যাকের মধ্যে বরাদ্দ করতে পারে
যতীন

6
স্ট্যাক কেবল হিপতে থাকা অবজেক্টের রেফারেন্স ধরে। কারণ স্ট্যাক সাফ হয়ে যায়, তাই রেফারেন্সও দেয়। অতএব এটি আবর্জনা সংগ্রহের জন্য উপলব্ধ
যতীন

6
@ জাটিন: আপনি ঠিক বলেছেন। যখন আমি স্মৃতি বোঝাতে চাইছিলাম তখন আমার অর্থ বস্তুগুলির জন্য রেফারেন্স-মান এবং আদিমদের জন্য মানগুলি (আমি মনে করি নবজাতী বিকাশকারীরাও জানেন যে অবজেক্টগুলি গাদা আছে)।
কোসা

4
@ নাম্বারী তবে রেফারেন্স মানটি যদি একটি ভাগ করা ভেরিয়েবলের দিকে নির্দেশ করে। তাহলে আমরা কীভাবে বলতে পারি যে এটি থ্রেড নিরাপদ?
এইচ.রাবি

4
@ হ্যাজদার: ভাগ হিসাবে কী পরিবর্তনশীল হয়? সেখান থেকে শুরু। হয় উদাহরণ বা শ্রেণি ভেরিয়েবল ঠিক আছে? স্থানীয় ভেরিয়েবল নয় এবং এই থ্রেডে মার্কো টপলিংক উত্তরটি পড়ুন, আমি মনে করি যে এটিই আপনি সম্পর্কে বিভ্রান্ত হয়ে পড়েছেন।
কোসা

19

স্থানীয় ভেরিয়েবলগুলি প্রতিটি থ্রেডের নিজস্ব স্ট্যাকে সংরক্ষণ করা হয়। এর অর্থ হ'ল স্থানীয় ভেরিয়েবলগুলি থ্রেডের মাঝে কখনই ভাগ করা যায় না। এর অর্থ হ'ল সমস্ত স্থানীয় আদিম পরিবর্তনশীল থ্রেড নিরাপদ safe

public void someMethod(){

   long threadSafeInt = 0;

   threadSafeInt++;
}

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


কৃষিতে ভুল হয়েছে, প্লিজ @ নাম্বারীর প্রতিক্রিয়া দেখে নিন
যতীন

যদি আপনি এই বিষয়টির দিকে ইঙ্গিত করছেন যে লোকালসেফআইন্ট ঠিক 0, তারপর 1 হবে এবং তারপরেও মুছে ফেলা ভাল। সুতরাং এটি দেখায় যে এই পরিবর্তনশীলটি থ্রেডগুলির মধ্যে ভাগ করা হয়নি এবং এর ফলে মাল্টি থ্রেডিং দ্বারা প্রভাবিত হয় না .. আমার মনে হয় আপনি এটি আরও কিছুটা উল্লেখ করতে পারেন যে থ্রেডসেফ সবসময় কেবল 0 বা 1
17

14

কার্যকারিতা সংজ্ঞা মত পদ্ধতি সম্পর্কে চিন্তা করুন। যখন দুটি থ্রেড একই পদ্ধতি চালায়, তারা কোনওভাবেই সম্পর্কিত হয় না। তারা প্রত্যেকে স্থানীয় স্থানীয় চলকটির নিজস্ব সংস্করণ তৈরি করবে এবং কোনওভাবেই একে অপরের সাথে ইন্টারঅ্যাক্ট করতে সক্ষম হবে না।

যদি ভেরিয়েবলগুলি স্থানীয় না হয় (যেমন শ্রেণীর স্তরের কোনও পদ্ধতির বাইরে উদাহরণস্বরূপ ভেরিয়েবলগুলি সংজ্ঞায়িত করা হয়), তবে সেগুলি দৃষ্টান্তের সাথে সংযুক্ত থাকে (কোনও পদ্ধতির একক রানের সাথে নয়)। এই ক্ষেত্রে একই পদ্ধতিতে চলমান দুটি থ্রেড উভয়ই একটি পরিবর্তনশীল দেখতে পান এবং এটি থ্রেড-নিরাপদ নয়।

এই দুটি ক্ষেত্রে বিবেচনা করুন:

public class NotThreadsafe {
    int x = 0;
    public int incrementX() {
        x++;
        return x;
    }
}

public class Threadsafe {
    public int getTwoTimesTwo() {
        int x = 1;
        x++;
        return x*x;
    }
}

প্রথমটিতে, একই উদাহরণে চলমান দুটি থ্রেড NotThreadsafeএকই x দেখতে পাবে। এটি বিপজ্জনক হতে পারে, কারণ থ্রেডগুলি এক্স পরিবর্তন করার চেষ্টা করছে! দ্বিতীয়টিতে, একই উদাহরণে চলমান দুটি থ্রেড Threadsafeসম্পূর্ণ ভিন্ন পরিবর্তনশীল দেখতে পাবে এবং একে অপরকে প্রভাবিত করতে পারে না।


6

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

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


4
আপনি বলছেন যে "বস্তুটিতে কলিং পদ্ধতিগুলি যেটি বোঝায় সেগুলি সহজাতভাবে থ্রেড-নিরাপদ নয়"। কিন্তু, কীভাবে কোনও পদ্ধতি স্থানীয় রেফারেন্স দ্বারা রেফারেন্স করা হয় - এই পদ্ধতির সুযোগে তাত্ক্ষণিকভাবে - দুটি থ্রেড দ্বারা ভাগ করা যায়? আপনি উদাহরণ দিয়ে নির্দেশ করতে পারেন?
অক্ষয় লোকুর

4
একটি স্থানীয় ভেরিয়েবল পদ্ধতিটির ক্ষেত্রের মধ্যে কোনও অবজেক্টকে ইনস্ট্যান্টিয়েটেড রাখতে পারে বা নাও রাখতে পারে, এটি প্রশ্নের অংশ ছিল না। এটি থাকলেও, পদ্ধতিটি ভাগ করে নেওয়া অবস্থায় অ্যাক্সেস করতে পারে।
মার্কো টপলনিক

6

নাম্বারীর মতো উত্তরগুলি ছাড়াও।

আমি উল্লেখ করতে চাই যে আপনি অ্যানয়মাস টাইপ পদ্ধতিতে একটি স্থানীয় ভেরিয়েবল ব্যবহার করতে পারেন:

এই পদ্ধতিটি অন্যান্য থ্রেডগুলিতে ডেকে আনা যেতে পারে যা থ্রেডসফিটির সাথে আপস করতে পারে, তাই জাভা ব্যাহত ধরনেরগুলিতে ব্যবহৃত সমস্ত স্থানীয় ভেরিয়েবলকে চূড়ান্ত হিসাবে ঘোষণা করতে বাধ্য করে।

এই অবৈধ কোড বিবেচনা করুন:

public void nonCompilableMethod() {
    int i=0;
    for(int t=0; t<100; t++)
    {
      new Thread(new Runnable() {
                    public void run() {
                      i++; //compile error, i must be final:
                      //Cannot refer to a non-final variable i inside an
                      //inner class defined in a different method
                    }
       }).start();
     }
  }

যদি জাভা এটি অনুমতি দেয় (যেমন সি # "ক্লোজার্স" এর মাধ্যমে করে), একটি স্থানীয় ভেরিয়েবল আর সব পরিস্থিতিতে থ্রেডসেফ হবে না। এই ক্ষেত্রে, iসমস্ত থ্রেডের শেষে মানটির গ্যারান্টি নেই 100


হাই ওয়েস্টন, উপরের আলোচনা এবং নীচের উত্তরগুলি থেকে আমি বুঝতে পেরেছিলাম যে জাভা সমস্ত স্থানীয় ভেরিয়েবলের থ্রেডসফটি নিশ্চিত করে। আমি কি সিঙ্ক্রোনাইজ করা কীওয়ার্ডের আসল ব্যবহারটি জানতে পারি? আপনি দয়া করে এই মত একটি উদাহরণ দিয়ে ব্যাখ্যা করতে পারেন?
প্রভু

5

থ্রেডের নিজস্ব স্ট্যাক থাকবে। দুটি থ্রেডে দুটি স্ট্যাক থাকবে এবং একটি থ্রেড এর স্ট্যাকটি অন্য থ্রেডের সাথে ভাগ করে না। স্থানীয় ভেরিয়েবলগুলি প্রতিটি থ্রেডের নিজস্ব স্ট্যাকে সংরক্ষণ করা হয়। এর অর্থ হ'ল স্থানীয় ভেরিয়েবলগুলি থ্রেডের মাঝে কখনই ভাগ করা যায় না।


3

মূলত শ্রেণীর তথ্য এবং ডেটা সঞ্চয় করার জন্য জাভাতে চার ধরণের স্টোরেজ রয়েছে:

পদ্ধতির ক্ষেত্র, গাদা, জাভা স্ট্যাক, পিসি

সুতরাং মেথড এরিয়া এবং হিপগুলি সমস্ত থ্রেড দ্বারা ভাগ করা হয়েছে তবে প্রতিটি থ্রেডের নিজস্ব জাভা স্ট্যাক এবং পিসি রয়েছে এবং এটি অন্য কোনও থ্রেড দ্বারা ভাগ করা যায় না।

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

@ ওয়েস্টনও ভাল উত্তর দিয়েছে।


1

থ্রেড স্ট্যাকের মধ্যে কেবল স্থানীয় ভেরিয়েবলগুলি সংরক্ষণ করা হয়।

স্থানীয় পরিবর্তনশীল যা primitive type(যেমন int, দীর্ঘ ...) এতে সঞ্চিত থাকে thread stackএবং ফলস্বরূপ - অন্যান্য থ্রেডে এটির অ্যাক্সেস নেই।

স্থানীয় পরিবর্তনশীল যা reference type(এর উত্তরসূরি Object) 2 অংশ থেকে থাকে - ঠিকানা (যা এতে সঞ্চিত থাকে thread stack) এবং অবজেক্ট (যা এতে সঞ্চিত থাকে heap)


class MyRunnable implements Runnable() {
    public void run() {
        method1();
    }

    void method1() {
        int intPrimitive = 1;

        method2();
    }

    void method2() {
        MyObject1 myObject1 = new MyObject1();
    }
}

class MyObject1 {
    MyObject2 myObject2 = new MyObject2();
}

class MyObject2 {
    MyObject3 myObject3 = MyObject3.shared;
}

class MyObject3 {
    static MyObject3 shared = new MyObject3();

    boolean b = false;
}

এখানে চিত্র বর্ণনা লিখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.