javaのスレッドの割込みについて

このQ&Aのポイント
  • javaのスレッド割込みに関する初心者の質問です。割込みの発生元でCNTに値を設定し、割込みの受信元でCNTの値を読込み、表示しています。
  • 割込みの発生元でCNTの値の設定と割込みの受信元でのCNTの値の読込みによる競合や処理の停滞について質問しています。
  • コードを参照しながらjavaのスレッドの割込みについての理解を深めたいと思っています。
回答を見る
  • ベストアンサー

javaのスレッドの割込みについて

javaのスレッド割込みに関する初心者の質問です。 割込みの発生元でCNTに値を設定し、割込みの受信元でCNTの値を読込み、表示しています。 下記のコードを参照ください。 Q1)CNTの値の設定と読込みで競合が発生する様なことはありませんか? 又は、処理が停滞するとか 以上、お手数をお掛けしますが、宜しくお願いします。 //割り込を発生するスレッド class threadA extends base{ private Thread target; public threadA(Thread targetA){ target = targetA; } public void run(){ for(int i = 0; i < 8;i++){ try{ System.out.print("."); Thread.sleep(1); CNT=i; target.interrupt(); }catch(InterruptedException e){ System.out.println("今割り込まれました: thread"); } } } } //スレッドからの割り込みを受信するルーチン class Sample108{ public static void main(String args[]){ //for(int i=0; i<2; i++){ classA obj = new classA(); obj.threadStart();//割り込みを受けるルーチン、この中で、割り込みを発生するルーチンを起動している //} } } //割り込みを受けるルーチン class classA extends base{ void threadStart(){ System.out.println("Start: main****"); threadA obj = new threadA(Thread.currentThread()); obj.start(); //Thread起動 //mainのルーチン for(int j = 0;j < 20; j++){ try{ Thread.sleep(1); System.out.print("*"); }catch(InterruptedException e){ System.out.println("今割り込まれました: classA CNT="+CNT); } } } } 以上

  • Java
  • 回答数4
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.4

CNT に volatile 修飾子が付いていない場合は誤った値が表示される可能性が有るかと。 マルチスレッド環境下でのフィールドの可視性の問題です。 各スレッドはフィールド値のキャッシュを持つ事が出来るので、synchronized ブロック内か volatile の付いたフィールド以外は、他のスレッドでの書き込まれた最新の値が見える保障はありません。 http://www.ne.jp/asahi/hishidama/home/tech/java/thread.html#h2_volatile http://www.ibm.com/developerworks/jp/java/library/j-jtp06197.html

その他の回答 (3)

noname#247307
noname#247307
回答No.3

>CNTはbaseクラスの中に下記の如く定義されています。 >class base extends Thread{ >public static CNT=0; >} あの、「タイプは何ですか」と訊いたんですが(苦笑)。まぁ、public static int CNT=0; と勝手に判断させてもらいましょう。ならプリミティブタイプですから競合による問題は発生しないはずです。

noname#247307
noname#247307
回答No.2

先に回答されている方が書いている通り、CNTは何なのでしょうか。どこにも宣言文がないのですが。 見たところ、ごく普通のint値であるように思えるのですが、Javaではプリミティブタイプはスレッドセーフなので、intなら競合による問題が発生することはないでしょう。が、CNTがインスタンスなら、そのクラスがどう定義されているかによって違ってきます。例えばイミュータブルなクラスなら問題は発生しないはずですがそうでないなら設計次第で競合による問題は発生する可能性があるでしょう。

bakabon_X
質問者

補足

shylockさま 御免なさい。 CNTはbaseクラスの中に下記の如く定義されています。 class base extends Thread{ public static CNT=0; }

  • y_shimizu
  • ベストアンサー率41% (27/65)
回答No.1

処理の概要がイマイチ掴めません。まずCNTの宣言の記載がないですし、interruptはInterruptedExceptionを必ず発生するものでもないので、CNTを出力したいタイミングがよくわかりません。また、競合とは何を意味していますか?

bakabon_X
質問者

補足

y_shimizu さま 回答有難うございます。 >処理の概要がイマイチ掴めません。 <---//割り込を発生するスレッド以下のコードを参照願います、またはPCでrunすれば ご理解できるのでは無いかと思います。 以上、宜しくお願いします。

関連するQ&A

  • javaの割込みのcatchに関する質問

    下記のコードはgenInterruptにて、割込みを10回発生させ、rcvInterruptでその 割込みをcatchするものです。 割込みの発生周期が1msの場合は、割込みのcatchは略10回受取ることが出来ますが、 割込みの発生周期が短い場合は、最初の2、3個受取るのみです。 Q1)割込みの発生周期が1msの場合には、全ての割込みをcatchすることが出来ますか? //========================== //Project: Interrupt(受信側セット)の確認 class T_thread extends Thread{ static int TIMES=20; public static void main(String args[]){ rcvInterrupt obj=new rcvInterrupt(); obj.start(); for (int i = 0 ; i <TIMES ; i++){ try{ Thread.sleep(1); //System.out.println("main: "+TIMES+"20回の1msタイマー待ち"); }catch(InterruptedException e){ } } } } class genInterrupt extends T_thread{ private Thread target; genInterrupt(Thread targetx){ this.target=targetx; } public void run(){ System.out.println("genInterupt start"); for (int i=0; i<10; i++){ try{ Thread.sleep(0); //割込みが殆ど捕らえられない //Thread.sleep(1); //割込みが全て捕らえられない事がたまにある target.interrupt(); } catch(InterruptedException e){ } } } } class rcvInterrupt extends T_thread{ int cnt=0; public void run(){ genInterrupt obj=new genInterrupt(Thread.currentThread()); obj.setPriority(Thread.MAX_PRIORITY); obj.start(); System.out.println("receiveInterupt start"); for (int i=0 ; i<20 ; i++){ try{ Thread.sleep(2); }catch(InterruptedException e){ System.out.println("get interrupt cnt="+cnt++); } } } } //========================== 以上、宜しくお願いします。

    • ベストアンサー
    • Java
  • スレッド間の送受信のコードについて

    下記のコードは、(以前お教え頂きました)『synchronized』を使用した、スレッド間の 送受信のコードですが、その代わりに、Interruptとか、Thread.sleep()を使用した、 コードに変更してみたいと思います。 Q1)そのコードをお教え頂けないでしょうか? class T_thread { public static void main(String args[]) { new rcvInterrupt().start(); } } class genInterrupt extends Thread { private rcvInterrupt target; genInterrupt(rcvInterrupt targetx) { this.target = targetx; } public void run() { System.out.println("genInterupt start"); for (int i = 0; i < 10; i++) { while (!target.isWaited) { // rcvInterruptがsynchronizedブロックに入るまで待ち合わせ // これがないと連続してsynchronizedしてしまう可能性がある } synchronized (target) { target.notifyAll(); target.isWaited = false; System.out.println("notify"); } } } } class rcvInterrupt extends Thread { volatile boolean isWaited; public synchronized void run() { new genInterrupt(this).start(); for (int i = 0; i < 10; i++) { try { isWaited = true; wait(); System.out.println("get interrupt cnt=" + i); } catch (InterruptedException e1) { } } } } 以上

    • ベストアンサー
    • Java
  • java Threadのsleepを途中で止める方

    今、訓練校に通っていて課題をだされていますが、どうもうまく行きませんのでお知恵を拝借したく思います。  java Threadのsleepを使用し、クイズの回答を10秒以内で答えるというものですが、 途中で入力をすると、次の問題の回答時間が異様に早くなり1秒ではなくなってしまいます。  こういう場合、入力をすれば、runメソッドが終わるというプログラムはどうやって書けばいいのか教えて頂きたく思います。 どうぞよろしくお願いいたします。 <下記、threadの部分だけですが、パッケージを使用するという課題のため無理やり使っています。> package pa; public class CountTest extends Thread { public void start() { super.start(); } public void run() { for (int i=10; i >= 1; i--) { try{ sleep(1000); System.out.print("⇒" ); }catch(InterruptedException e){} } System.out.println(""); for (int i=1; i >= 1; i--) { / } System.out.println("Time up "); System.out.println(""); System.out.println("1-4で答えを記入してください"); }

    • ベストアンサー
    • Java
  • extendsの使い方

    public class ThreadSample3 { public static void main(String[] args) { ThreadA ta = new ThreadA(); ThreadB tb = new ThreadB(); ta.start(); tb.start(); } } class ThreadA extends Thread { public void run() { try { for(int i = 0; i < 10; i++) { Thread.sleep(1000); System.out.println("ThreadA"); } } catch (InterruptedException e) { } } } class ThreadB extends Thread { public void run() { try { for(int i = 0; i < 10; i++) { Thread.sleep(2000); System.out.println("ThreadB"); } } catch (InterruptedException e) { } } } これは、ThreadAとThreadBを10回ずつ表示させるプログラムなのですが、extendsは子供と親の関係に当たり、例えば親クラスボールだったら子クラスが野球ボールやゴルフボールになると習いました。 class ThreadA extends Thread{ の部分はThreadとThreadAが親子関係になっていますか? またどうして子クラスの名前と親クラスの名前はこう書かないといけないですか。 

    • ベストアンサー
    • Java
  • java 選択肢に制限時間を設ける

    こんにちは. 現在javaでプログラムを組んでいるのですが,その中で選択肢を表示させる部分があります. この選択肢の選択に制限時間を設けたいのですが,うまくいきません. このプログラムの実現のためにどんな方法があるでしょうか? どなたかご教授お願いします. なお, public class time extends Thread { public void run() { for (int i = 3; i >= 0 ; i--) { try { sleep(1000); } catch (InterruptedException e) {} System.out.println(i); } } public static void main(String[] args) { time t = new time(); t.start(); try { System.out.println("スレッド t の終了を待機します。"); t.join(); // カウントダウンが終了するのを待つ System.out.println("スレッド t が終了しました。"); } catch (InterruptedException e) {} } } こちらのソースを参考にプログラムを書いてみましたがだめでした.

    • ベストアンサー
    • Java
  • スレッド1とスレッド2を交互に実行するには?

    スレッド1→スレッド2→スレッド1・・・と同期を取り合いながら交互にスレッドを動かしたいのですが、Thread.getState()を用いないで実現するよい方法はないでしょうか? どうしてもデッドロックが発生しうる方法しか思いつかず困っています。 例えば以下のプログラムで1212と交互に表示させたい場合です。 以下のプログラムは当然デッドロックになりますが、やりたいことを伝えるために載せておきます。 Object obj; //スレッド間通信用のobject class Test1 extends Thread {  public void run() {   while(true) {    System.out.print("1");    synchronized (obj) {     obj.notify();//相手をnotifyして     obj.wait();//自分はwait    }   }  } } class Test2 extends Thread {  public void run() {   while(true) {    System.out.print("2");    synchronized (obj) {     obj.notify();     obj.wait();    }   }  } } new Test1().start(); new Test2().start();

    • ベストアンサー
    • Java
  • Threadに関するの質問

    このプログラムに synchronized , wait(), notify()を加えることで、 stackBody[]配列をオーバーやアンダーフローしないようにできるのでしょうか。お助け下さい! public class test { public static void main(String args[]) { Stack stack = new Stack(5); Pusher pusher = new Pusher(stack); Popper popper = new Popper(stack); pusher.start(); popper.start(); } } class Stack { private int stackSize; private int stackPointer; private int stackBody[]; public Stack(){ this(10); } public Stack(int size){ stackSize = size; stackBody = new int[size]; stackPointer = 0; } public void push(int value){ if(stackSize == stackPointer){ // } stackBody[stackPointer++] = value; } public int pop(){ if(stackPointer == 0){ // } return stackBody[--stackPointer]; } } class Pusher extends Thread { Stack s; public Pusher(Stack s) { this.s = s; } public void run() { int n, interval; for(int i = 0; i < 10; i ++) { n = (int)(100.0 * Math.random()); interval = (int)(100.0 * Math.random()); s.push(n); System.out.println("Pusher:" + n); try{ Thread.sleep(interval); }catch(InterruptedException e) {} } System.out.println("Push 終了"); } } class Popper extends Thread { Stack s; public Popper(Stack s) { this.s = s; } public void run(){ int n, interval; for(int i = 0; i < 10; i++){ interval = (int)(100.0 * Math.random()); n = s.pop(); System.out.println("Popper:" + n); try{ Thread.sleep(interval); }catch(InterruptedException e) {} } System.out.println("Popper 終了"); } }

    • ベストアンサー
    • Java
  • [javaプログラムについて] うまく動きません。

    import java.*; class Test { void main() { Th th1 = new Th("01スレッド"); Th th2 = new Th("02スレッド"); th1.start(); th2.start(); } } class Th extends Thread { void run(String pri) { for (int i=0;i<5;i++) { System.out.println(pri + " : " + i); } } } スレッドの使い方がいまいちよく分かりません。 どこが間違っているのか教えてください。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • Thread.Abortメソッド後の処理について

    Thread.abortメソッドについて分からないことがあったので,助言が頂けると嬉しいです. Thread.Abort () を発生させると,通常そこでスレッドが終了するということなので,その後のスレッド内の処理はスルーされると思っていたのですが,下記コードですとその後の pictureBox1.Image = null;も実行されている様です. mainでスレッド作成→threadAの停止になると考えていたのですが,delegate内では反映されないのでしょうか? Thread thread_a; //スレッド delegate void Del(); private void main(object sender, EventArgs e) { //スレッドを開始 thread_a = new Thread(new ThreadStart(threadA)); thread_a.Start(); } private void threadA() { new Thread(new ThreadStart(delegate { Invoke((Del)delegate { thread_a.Abort(); //画像を消去する pictureBox1.Image = null; }); })).Start(); }

  • Javaのスレッドに関して質問です

    Assistantクラスを使い待機状態と再開を確認できるプログラムの作成 loafとrestartメソッドを設ける workメソッドが呼ばれる度loafを呼び出す Managerクラスを定義 checkメソッドを設け、Assistantをcheckし続ける loaf状態ならrestartさせる (Managerクラスはデーモンスレッド) ということなんですが、いまいちうまくいきません さぼっても復帰してくれません public class Assistant implements Runnable { private String name; private Chore c; public Assistant(String name, Chore c) { this.name = name; this.c = c; } public void run() { work(); } public void work() { while (true) { synchronized (c) { if (c.doEnd()) break; System.out.println(name + " : " + c.digest()); loaf(); } } } public synchronized void loaf() { try { c.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void restart() { c.notify(); } } public class Chore { private String name; private int step; private int id; public Chore(String name) { this.name = name; this.step = this.name.length(); this.id = 0; } public synchronized String digest() { String message = "" + id + name.charAt(id); try { Thread.sleep(500); } catch (InterruptedException ie) { } id++; return message; } public synchronized boolean doEnd() { return id >= step; } } public class Manager extends Thread { private String name; private Assistant a; public Manager(String name) { this.name = name; } public void run() { check(); } public void check() { a.restart(); } } public class Test { public static void main(String[] args) { Chore[] ch = { new Chore("掃除"), new Chore("プリント印刷"), new Chore("出欠データ入力") }; Assistant[] a = { new Assistant("あ", ch[0]), new Assistant("\tい", ch[1]), new Assistant("\t\tう", ch[2] }; Thread[] t = new Thread[a.length]; for (int i = 0; i < t.length; i++) { t[i] = new Thread(a[i]); } for (int i = 0; i < t.length; i++) { t[i].start(); } Manager m = new Manager("監査"); m.setDaemon(true); m.start(); for (int i = 0; i < t.length; i++) { try { t[i].join(); } catch( InterruptedException ie ) { } } }

    • ベストアンサー
    • Java

専門家に質問してみよう