Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Синхронизация 2-х потоков. Помогите, скоро сессия vol. 2  (Прочитано 41927 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« : 05-12-2007 20:29 » 

Привет, у меня бока с синхронизацыей 2 - потоков, которые рисуют летящую птичку( в которую юзверь палит базукой).
1 поток - крылья вверх, 2 - вниз. Но что б вас не нагружать, просто обьясните, почему потоки выводять свои имена не по порядку. Синхронайзед в Ява это ж как критикал секшн в Си, или других языках7. Ведь если 1 поток зашел в синхрон. блок, то 2 ждёт, и получает квант времени от проца буит вызыватся после 1 так как приоритет больше, а у меня получается, что 1 может вызыватся 2 раза подряд, или 3, кароче никакой последовательности. Если знаете, то скажите, как без thread.sleep() сделать так шоб 2 "всегда" ишол после 1, и никак иначе.

Код:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

public class my_game extends Applet
{
myThread myT;// сюда буим пихать перед загрузкой отрисовки поток
String s_name;

Image img_baz;

int baz_h = 100;
int baz_w = 50;
int baz_x = 125;


public void init()
{
    this.setSize(500, 500);
    this.setBackground(new Color(81,185,89));
   
try {
                       img_baz = ImageIO.read(new File("Bazoooka.jpg"));
        } catch (IOException e) {
        System.out.println("Error!");
        }

     myThread myt1 = new myThread(this,"ptichka1.jpg", "1");
     myThread myt2 = new myThread(this,"ptichka2.jpg", "2");
     myt1.start();
     myt2.start();
       
        addKeyListener(new myKeyAdapter(this));

}

synchronized public void getP(myThread myTparent){// а вот и виновник...

myT = myTparent;//пихаим поток в наш екз. для данных по отрисовке

System.out.println(myT.name);

s_name = myT.name;

repaint();// отрисовка

}

public void paint(Graphics g)
{
g.drawImage(img_baz, baz_x, this.getHeight() - baz_h, baz_w ,baz_h , null);

g.drawImage(myT.t_img, myT.t_img_x,0, myT.t_img_w ,myT.t_img_h  , null);// отрисовка
}


}

class myKeyAdapter extends KeyAdapter
{

my_game applet;

public myKeyAdapter(my_game applet_parent){
this.applet = applet_parent;
}

public void keyPressed(KeyEvent ke)
{
if(ke.getKeyCode() == 39) {this.applet.baz_x+=10; this.applet.repaint();}
if(ke.getKeyCode() == 37) {this.applet.baz_x-=10; this.applet.repaint();}
}
}

class myThread extends Thread{

my_game applet;

Image t_img;

String name;

int t_img_h = 50;
int t_img_w = 50;
int t_img_x = 0;
int t_speed = 5;


public myThread(my_game appletparent, String path, String nameparent){
name = nameparent;
                applet = appletparent;
try{
t_img = ImageIO.read(new File(path));
}catch(IOException e){System.out.println("Erooor!");}
}

public void run(){
for(int i = 0; i<50; i++){

this.t_img_x +=t_speed;

this.applet.s_name = this.name;

                        this.applet.getP(this);// вызов синхр. функции

//try{
// this.sleep(1000);
//}catch(InterruptedException e){System.out.println("jjj");}

}
}

}

а вот шо мне видаёт еклипс: 1111111111112222222222222222222222222222222222222222222222222211111111111111111111111111111111111111

« Последнее редактирование: 05-12-2007 20:37 от Sandric » Записан

We hate love, we love hate...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 05-12-2007 21:24 » 

Никак. Как винда запускает потоки, это политика самой винды. Из пользовательского приложения практически никак нельзя влиять на этот процесс. Только досрочно завершать выполнение потока при помоши sleep. В Java точно не знаю. Но  в WinAPI sleep с параметром 0 завершает поток и если нет потоков с таким же приоритетом в очереди потоков, винда может повторно запустить поток. Кстати, а зачем такое изврашение, что один поток "поднимает",  а второй "опускает" крылья у бедной птици? Чем тебе не подходит обычный таймер?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #2 : 05-12-2007 21:35 » 

Задание такое. А слип етот не из апи, а встроеный метод класса поток у самой явы. Тю, блин, шота я тада ваще не врубаюсь, как это "винда сама решаит", я когдато мютексы делал всё там по очереди ишло. А без слипа нада сделать тошо по моему ето бред, полагатся тока на примерную, на глаз оценку задержки цп. У явы есь такая штука как wait notity notifyall функции, и с ними мона ожидать, например вып. пока не выполницца което условие, для етого я там даже поле посавил в прогу p_name шоб сверять имя пред потока с тепер, и выполнять тока по наступленни события для разблокировки, от тока оно у меня не пашит, и выводит про коета переполнение( видно вайла в getP ). Ну хоть как-та можна ж его организовать! Ато у меня не мархант а койта чернобыльский курятник палучаицца! Жаль
Записан

We hate love, we love hate...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 05-12-2007 21:52 » 

Sandric, Пиши чуть чуть более грамотно. У меня по русскому тоже были двойки. Но для этого сушествует тезарус, хотя бы в том же ворде.

Я специфику Java не знаю и код честно говоря не смотрел,  поэтому буду говорить на примере WinAPI. Смотри, есть функция в WinAPI, которая ожидает какой либо событие. При этом thread исключается из очереди на выполнение. Еше такая деталь. Хоть и Windows, *nix и мультизадачные среды, но нужно понимать, что на однопроцессорной платформе это все равно псевдо мультизадачность. В данный конкретный момент времени работает только один поток. Он отрабатывает свой квант времени, система переключает процессор на другой поток. Просто эта смена случается довольно часто, поэтому в человеческом измерении мы не видим разници между псевдо и настояшей мультизадачностью.
Исходя из этого и твоего обьяснения проблемы, хорошо, ты освободил секцию, и тут же ее пытаешся захватить. Но второй поток то не работает в это время. Он просто физически не может захватить секцию. Так он и будет висеть, пока ему не повезет. Не надейся на то, как будут работать и запускаться потоки. На это ты не можеш влиять.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #4 : 05-12-2007 22:11 » 

Цитата
Sandric, Пиши чуть чуть более грамотно. У меня по русскому тоже были двойки.
Я постараюсь, просто у меня и русского никогда не било, это не мой родной язик, но я постараюсь. Улыбаюсь
Цитата
Не надейся на то, как будут работать и запускаться потоки. На это ты не можеш влиять.
Пасибо, не очень обнадёживающе... Теперь нужно както сообщить об этом моему преподу... С ума сойти...
Записан

We hate love, we love hate...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 05-12-2007 22:27 » 

Можно сделать ход конем Улыбаюсь. Создать 2 критичиские секции. Первую секцию использовать как обычно, а вторую как сигнал, что второй поток еше не отработал.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 06-12-2007 05:23 » 

Sandric, с крисеками в двух потоках не справишься, нужен мутекс или события. А ещё лучше могу предложит вариант : Финч упоминал про таймер. Если тебе обязательно нужно 2 потока - сделай один поток таймером (без использования сообщения WM_TIMER)
(опять же , всё гоню под с++ Улыбаюсь - просто мысль выдаю)
Один поток (таймер) делает такую штуку

Код:

pars_for_timer
{
  DWORD dwdTimer1;
  DWORD dwdTimer1;
  DWORD bExit1;
  DWORD bExit2;
};

timer_thread(void* pars)
{
   pars_for_timer* P1= (pars_for_timer*)pars; //глобальные параметры - счётчики таймеров
   
  for(;!P1->bExit1;)
  {
    Sleep(50);
   
    //инкремент/декремент счётчиков
    InterlockedIncrement(P1->dwdTimer1);
    InterlockedIncrement(P1->dwdTimer2);
  }
  return 0;
};

а второй поток ТОЛЬКО ЧИТАЕТ параметры

Код:
movie_thread(void* pars)
{
   const pars_for_timer* P2= (const pars_for_timer*)pars;

  for(;!P2->bExit2;)
  {
  }
 
  return 0;
}

для завершения потоков надо сделать

Код:
InterlockedIncrement(PAR->bExit1);
InterlockedIncrement(PAR->bExit2);
Sleep(2000); //сколько то ждём , чтоб завершились потоки

для контроля завершённости потоков - можно в конце потока, перед return 0, вновь отнять от ExitN - и дождаться нулей (там, где сейчас Sleep(2000) )
« Последнее редактирование: 06-12-2007 05:26 от Алексей1153++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 06-12-2007 07:23 » 

Алексей1153++, это все таки Java - забудь про Win32 API - здесь свое, совершенно независимое от ОС. Общее у них только то, что виртуальная машина, все-таки, работает в ОС и зависит от ее повадок.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 06-12-2007 08:32 » 

понятно. Говорю же - только идею толкнул
Записан

Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #9 : 06-12-2007 15:25 » 

Пасибо всем за ответы, Finch
Цитата
Создать 2 критичиские секции. Первую секцию использовать как обычно, а вторую как сигнал, что второй поток еше не отработал.
Мой мозг вобше отказ. понимать такое, но если би оно и пахало, то было би сильно закрученно, и препод би подумал что то не я писал лабу. Не понял
2 Алексей1153++. Спасибо за помощь, но я сам знаю что такое мютексы, но, кстати не понимаю, почему нильзя для 2 потоков использовать критикал секшнс, они ж у меня с 1 процесса. Всё дело в том, что ява работаит с виртуальной машиной, а не с апи, и организованы спец функции для того что б не терять мультиплатформенность.
Я глубоко забил и тупо поставил слип на 100 мсек., и всё идёт нормально. След. лаба - сделать компонент ява бинс, так шо не пропадайте, если будет что-то не понятно, будет часть 3 Ага
Записан

We hate love, we love hate...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 06-12-2007 16:59 » 

но, кстати не понимаю, почему нильзя для 2 потоков использовать критикал секшнс, они ж у меня с 1 процесса. Всё дело в том, что ява работаит

из МСДН:
Цитата
An object of class CCriticalSection represents a "critical section" — a synchronization object that allows one thread at a time to access a resource or section of code. Critical sections are useful when only one thread at a time can be allowed to modify data or some other controlled resource. For example, adding nodes to a linked list is a process that should only be allowed by one thread at a time. By using a CCriticalSection object to control the linked list, only one thread at a time can gain access to the list.

возможно для явы это и не катит, не спорю )

хммм, это же мфс-ишный класс , а поглядел для апишного объекта -
Цитата
Critical section objects provide synchronization similar to that provided by mutex objects, except that critical section objects can be used only by the threads of a single process.

почему разницо ?
« Последнее редактирование: 06-12-2007 17:08 от Алексей1153++ » Записан

Asver
Постоялец

by
Offline Offline
Пол: Мужской

« Ответ #11 : 06-12-2007 19:26 » 

Почитай для начала http://www.skipy.ru/technics/synchronization.html . Там все понятно написано. И Вообще на этом сайте очень много интересного для начинающего.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 06-12-2007 19:35 » 

Offtopic:

ой, какой дизайн тормозной...
ну это про яву, а не ответ на вопрос про разницу работы крисеков в классе МФС и ядре ) Да вообще, я оффтоп развёл тут ))
Поставлю в угол.

Записан

Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #13 : 07-12-2007 12:31 » 

Вау, [CENSORED] классный сайт, всем советую, у меня в майнфилде в полоске главных сайтов! Пасибо! Класс!
Записан

We hate love, we love hate...
Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #14 : 07-12-2007 17:03 » 

Люди, если я пойму почему не пашит это, наверно сделаю лабу! F1!

Код:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

public class mainclass extends Applet
{
myThread myT;
String s_name;

Object sync;

public void init()
{
this.setSize(500, 500);
    this.setBackground(new Color(81,185,89));
   
        myThread myt1 = new myThread(this,"1");
     myThread myt2 = new myThread(this,"2");
    
     s_name = myt2.name;
    
     myt1.start();
     myt2.start();
       
}

synchronized public void getP(myThread myTparent){

System.out.println(myTparent.name+" In da func...");

myT = myTparent;

if(s_name == myT.name)
try{
System.out.println(myT.name+" Begin 2 Wait...");
myT.wait();
}catch(InterruptedException e){System.out.println("jjj");

System.out.println(myT.name + " says: Menay s_name");

s_name = myT.name;

System.out.println(myT.name + " says: Prosnites Vse!");

notifyAll();

System.out.println(myT.name + " Vihodit iz func");

}

}

class myThread extends Thread{

mainclass applet;

String name;

public myThread(mainclass appletparent, String nameparent){
name = nameparent;
applet = appletparent;

}

public void run(){
for(int i = 0; i<10; i++){

System.out.println(this.name+" Vhodit v func...");
this.applet.getP(this);

}

}
}
}

Вот что выдаётса:

Цитата
Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
   at java.lang.Object.wait(Native Method)
   at java.lang.Object.wait(Object.java:485)
   at mainclass.getP(mainclass.java:38)
   at mainclass$myThread.run(mainclass.java:79)
2 Vhodit v func...
2 In da func...
2 Begin 2 Wait...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...
1 Vhodit v func...
1 In da func...

 А черт его знает... F1
« Последнее редактирование: 07-12-2007 17:06 от Sandric » Записан

We hate love, we love hate...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 07-12-2007 18:56 » 

в читабельном виде (для тех, кто будет помогать Улыбаюсь ) :
Код:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

public class mainclass extends Applet
{
myThread myT;
String s_name;

Object sync;

public void init()
{
this.setSize(500, 500);
this.setBackground(new Color(81,185,89));

    myThread myt1 = new myThread(this,"1");
myThread myt2 = new myThread(this,"2");

s_name = myt2.name;

myt1.start();
myt2.start();

}

synchronized public void getP(myThread myTparent)
{

System.out.println(myTparent.name+" In da func...");

myT = myTparent;

if(s_name == myT.name)
{
try
{
System.out.println(myT.name+" Begin 2 Wait...");
myT.wait();
}
catch(InterruptedException e)
{
System.out.println("jjj");

System.out.println(myT.name + " says: Menay s_name");

s_name = myT.name;

System.out.println(myT.name + " says: Prosnites Vse!");

notifyAll();

System.out.println(myT.name + " Vihodit iz func");

}
}

}

class myThread extends Thread
{

mainclass applet;

String name;

public myThread(mainclass appletparent, String nameparent)
{
name = nameparent;
applet = appletparent;

}

public void run()
{
for(int i = 0; i<10; i++)
{

System.out.println(this.name+" Vhodit v func...");
this.applet.getP(this);

}

}
}
}

сам вижу только такую вещь:

первый поток не заходит в блок
Код:
if(s_name == myT.name)
{
}
, ибо там имя "2".

второй , соответственно, заходит , и намертво повисает в блоке try:
Код:
try
{
System.out.println(myT.name+" Begin 2 Wait...");
myT.wait();//ТУТ
}

и всё , собствено ) Пока цикл 1-го не кончится
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 07-12-2007 18:57 » 

в блоке
Код:
catch(InterruptedException e)
{
System.out.println("jjj");
System.out.println(myT.name + " says: Menay s_name");
s_name = myT.name;
System.out.println(myT.name + " says: Prosnites Vse!");
notifyAll();
System.out.println(myT.name + " Vihodit iz func");
}
программа не бывает вообще - зачем он только ?
Записан

Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #17 : 07-12-2007 19:49 » 

Ой, я дико извиняюсь, не стесняйтесь, материтесь, я дужку забыл, гыгы (голосом Регины Дубовицкой...) код такой:

Код:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

public class mainclass extends Applet
{
myThread myT;
String s_name;

Object sync;

public void init()
{
this.setSize(500, 500);
    this.setBackground(new Color(81,185,89));
   
         myThread myt1 = new myThread(this,"1");
     myThread myt2 = new myThread(this,"2");
     
     s_name = myt2.name;
     
     myt1.start();
     myt2.start();
       
}

synchronized public void getP(myThread myTparent){

System.out.println(myTparent.name+" In da func...");

myT = myTparent;

if(s_name == myT.name)
try{
System.out.println(myT.name+" Begin 2 Wait...");
myT.wait();
}catch(InterruptedException e){System.out.println("jjj");}// вот тут я и провмыкал...

System.out.println(myT.name + " says: Menay s_name");

s_name = myT.name;

System.out.println(myT.name + " says: Prosnites Vse!");

notifyAll();

System.out.println(myT.name + " Vihodit iz func");

}



class myThread extends Thread{

mainclass applet;

String name;

public myThread(mainclass appletparent, String nameparent){
name = nameparent;
applet = appletparent;

}

public void run(){
for(int i = 0; i<10; i++){
/*
while(this.applet.s_name == this.name)
try{
System.out.println(this.name+" Begin 2 Wait...");
wait();
}catch(InterruptedException e){System.out.println("jjj");
*/
//}

System.out.println(this.name+" Vhodit v func...");
this.applet.getP(this);
}

}
}
}

а ответ теперь такой:

Цитата
2 Vhodit v func...
2 In da func...
2 Begin 2 Wait...
Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
   at java.lang.Object.wait(Native Method)
   at java.lang.Object.wait(Object.java:485)
   at mainclass.getP(mainclass.java:38)
   at mainclass$myThread.run(mainclass.java:79)
1 Vhodit v func...
1 In da func...
1 says: Menay s_name
1 says: Prosnites Vse!
1 Vihodit iz func
1 Vhodit v func...
1 In da func...
1 Begin 2 Wait...
Exception in thread "Thread-3" java.lang.IllegalMonitorStateException
   at java.lang.Object.wait(Native Method)
   at java.lang.Object.wait(Object.java:485)
   at mainclass.getP(mainclass.java:38)
   at mainclass$myThread.run(mainclass.java:79)

Короче, они не просыпаются, а как тогда сделать, что б просыпались?
Записан

We hate love, we love hate...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 07-12-2007 20:00 » 

а зачем ты их усыпляешь то ? Возобновить поток -что нибудь вроде resume ...
Где возобновлять потоки ты будешь - я вообще не в курсе , ты логику не продумал, похоже )

зы ты же вроде хотел объекты синхронизации использовать ?
Записан

Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #19 : 07-12-2007 20:09 » 

Цитата
Где возобновлять потоки ты будешь - я вообще не в курсе , ты логику не продумал, похоже )

возобновление потоков (какогото из них) notifyAll() - в функции прописано, но я не знаю, как его вызывать, надо ли держать указатель на екз. того потока, который в момент возобновления ждёт? Я ж у вас спрашиваю, глупенький я... Жаль
Записан

We hate love, we love hate...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 07-12-2007 20:24 » 

(а я ещё хуже - я явы не знаю Улыбаюсь))  пишу только потому, что остальные почему то молчат... )

конечно через указатель только - а как ещё ? Сам себя поток может тормознуть, а возобновить уже сам себя не может
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #21 : 07-12-2007 20:27 » 

Извините, я не местный, а вообще о чем речь идет?
Второй день слежу за событиями и никак понять не могу, а причем здесь потоки?
Есть два действия:
1.Руки вверх
2.Руки вниз
Тьфу, не руки, а крылья.
Так вот: почему они должны быть в потоках?
Есть один поток полет, но чтоб лететь нужно махать (махнули вниз вызвали процесс взмаха вверх, махнул вверх - вызываем мах вниз) и так до тех пор пока птичка не встретится со снарядом

А потоков действительно должно быть несколько, но никак не связанных с "маханием"

Один поток - полет снаряда от базуки
Второй - полет птички
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 07-12-2007 20:38 » 

Sla, препод велев 2 потока Улыбаюсь)))

а ведь я же предлагал один поток как таймер юзать, другой - рабочий
Записан

Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #23 : 07-12-2007 20:48 » 

Та не, всё намного проще - нада было всунуть обработчик исключения на странное поведение монитора синхронайзед функции, ну это шоб не писало бред типа
Цитата
Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
   at java.lang.Object.wait(Native Method)
   at java.lang.Object.wait(Object.java:485)
   at mainclass.getP(mainclass.java:38)
   at mainclass$myThread.run(mainclass.java:79)
и т.п., и писать не текущий_поток.wait(), a просто wait(), так что
Цитата
конечно через указатель только - а как ещё ? Сам себя поток может тормознуть, а возобновить уже сам себя не может
как раз и не надо было. Оказ. вайт и нотифи не синхронизированны, и вызываются только из синхронайзед функций, стопаясь "в" их же исполняемый екземплярах, короче, можно было бы написать внутри рана класса потока шото типа
Код:
this.applet.getP.wait()

если при этом сам синх. метод написан так:
Код:
public void getP(){
    synchronized(this){
        // code
    }
}
В общем, меньше возни чем с апи, но пока осознаиш, как именно нада, можна морально разложится... Ага
Записан

We hate love, we love hate...
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #24 : 07-12-2007 20:49 » 

Так не махать же крыльями в потоке

Если быстро-быстро махать, то завихрения получаются, так и в штопор уйти можно, что и получается.
"Ноги, ноги! Хвост! " (с)

Два потока  есть
Выстрел (снаряд)
Махание.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #25 : 07-12-2007 20:55 » 

Sla, ты не понял, пан сказал - делать нада, а то шо 1 поток- выстрел, 2 - махание, ты не увидеш именно поочередной работы 2 потоков, конешна, у меня будет поток для стреляния, и для перемещения базуки, и будут они с полиморфизмом, и чики-пуки, этот пример именно для усвоения условной работы потоков через синхронайзед функции, кстати вот и он, а то может кому то и понадобатса:

Код:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

public class mainclass extends Applet
{
myThread myT;
String s_name;

Object sync;

public void init()
{
this.setSize(500, 500);
    this.setBackground(new Color(81,185,89));
   
         myThread myt1 = new myThread(this,"1");
     myThread myt2 = new myThread(this,"2");
     
     s_name = myt2.name;
     
     myt1.start();
     myt2.start();
       
}

synchronized public void getP(myThread myTparent){

System.out.println(myTparent.name+" In da func...");

myT = myTparent;

if(s_name == myT.name)
try{
System.out.println(myT.name+" Begin 2 Wait...");
myT.wait();
}catch(InterruptedException e){System.out.println("jjj");

System.out.println(myT.name + " says: Menay s_name");

s_name = myT.name;

System.out.println(myT.name + " says: Prosnites Vse!");

notifyAll();

System.out.println(myT.name + " Vihodit iz func");

}

}

class myThread extends Thread{

mainclass applet;

String name;

public myThread(mainclass appletparent, String nameparent){
name = nameparent;
applet = appletparent;

}

public void run(){
for(int i = 0; i<10; i++){

System.out.println(this.name+" Vhodit v func...");
this.applet.getP(this);

}

}
}
}
Я тему пока не закрываю, а то ишшо нада буит саму игру доделать
Записан

We hate love, we love hate...
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #26 : 07-12-2007 21:04 » 

Пан зрозумів, що якийсь дядька молодчику мозги пудрит.
Ты ведь не привел Задания, а просто сказал:" Преподаватель сказал в два потока".
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sandric
Wimdows SUX
Участник

ua
Offline Offline
Пол: Мужской
I hate myself and I wanna die


« Ответ #27 : 08-12-2007 07:25 » 

Цитата
Пан зрозумів, що якийсь дядька молодчику мозги пудрит.
У! Крут! Отлично
А что касаетса задания - игра. Все части игры - обрабатываютса потоками, но при этом нужна синхронизация, и по настоянию препода, "если возможно" реализовать в чём-то "поочерёдность" работы потоков, что бы было наглядно видно ихнее управление. Вот вобщим и задание.
Записан

We hate love, we love hate...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 08-12-2007 11:31 » 

тогда надо такую вещь замутить : один поток - менеджер , поочереди раздаёт кванты времени потокам , остальные потоки делают квант работы и зависают.
Записан

Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 08-12-2007 11:48 » 

Хм... У меня задача "как заставить 2 потока работать поочерёдно" почему-то сразу ассоциируется с организацией двух событий (event-ов) - нас так ещё в университете на параллельных компьютерных технологиях учили. Делается так: первый поток ждёт наступления первого эвента, второй - второго. Соответственно, первый при успешном завершении ожидания делает своё чёрное дело и выставляет второй эвент, а второй поток - наоборот, выставляет первый эвент. Остаётся только при запуске этих потоков из основного потока установить какой-то из двух эвентов, задав последовательность. Разве не так?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #30 : 08-12-2007 12:25 » 

Вад, дык я об этом и тылдычу, а он мені : "Вчитель так сказав"
Алексей1153++, почти, наверное прав.
Менеджером выступает, что-то, что инициирует потоки, в данном случае я пока увидел три потока (базука, снаряд, птичка) эти три потока не синхронны.

Птичка летит - два потока, но они последовательные, но не синхронны.

Хотя.... Пойду почитаю что-нибудь про синхронизацию. может я просто не понимаю что такое синхронная работа.

Т.е. для меня синхронизация - это приблизительно как синхронное плавание (прыжки в воду, на батуте)  два и более процессов делают одно и то же и в некие моменты они корректируют свои движения.
Также синхронизация - это когда независимые процессы в какой-то момент времени получают информацию от другого потока
Offtopic:

А тут анекдот про петуха и курицу:
Петух: Н едогоню так согреюсь
Курица: А не слишком ли я быстро бегу?
Поставлю в угол.

ничего не напомнило? в какой-то момент они засинхронизируются.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #31 : 08-12-2007 12:47 » 

Ну, мы тоже в своё время делали подобные простенькие лабы, где нужно было наглядно демонстрировать, чтобы действия выполнялись потоками в очерёдности 1->2->..->N->1->2->..->N->... Поэтому мне понятно, почему именно так задание поставил преподаватель: чтобы студенты научились согласовывать работу потоков не только по принципу защиты данных критическими секциями, но и по принципу построения определённой требуемой очерёдности. Конкретно для двух потоков, если не предполагается как-то расширять эту схему, легче всего, на мой взгляд, для упорядочивания использовать схему, которую я выше описал. Возможно, есть схемы проще, но в голову они мне сейчас не приходят Улыбаюсь
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #32 : 08-12-2007 16:05 » 

Давайте отойдем от базуки и птички с ее крыльями. Ну никак не вкладывается махание крыльями в синхронизацию.

Живой пример:
Есть некая СУБД.
Есть некая запись.
Есть несколько процессов работающих с этой записью.

Чтобы привести конкретный пример - пожайлуста.
Банковский счет (БСч)
На Бсч лежит 1млн эквивалента.
Некий процесс (поток) П1 обращается к БСч и видит там 1 млн.
Другой поток П2 обращается к БСч и видит там 1 млн.
П1 снимает со счета половину от 1 млн.
П2 снимает со счета 0.75 от 1 млн.
Все! Банкиры в тюрьме!

Пытаемся исправить ситуацию.
П1 блокирует счет на время выполнения операций по состоянию БСч.
П2 ждет окончания блокировки. И только после окончания блокировки П2 получает доступ к состоянию БСч
Все. И волки целы и овцы сыты Улыбаюсь
 
Это то же синхронизация.
два потока работают до возникновения "критической ситуации" независимо, работают critical section. При возникновении критического события поток, ждет окончания "блокировки".
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #33 : 09-12-2007 10:52 » 

Согласен с приведённым примером. Но возможны же и другие ситуации, когда требуется обеспечить выполнение функций в разных потоках в определённой последовательности. Это не эквивалентные по своим задачам потоки (например, первый поток подготавливает какие-то данные для другого потока).
Пусть какой-то один компонент в своём потоке выполняет запросы к другому компоненту и ждёт ответа на отправленный запрос, прежде чем выполнять следующий запрос. В свою очередь, получатель запроса обрабатывает его, возвращая результат. Конечно, первый компонент может на свой страх и риск выполнять синхронный запрос ко второму, но ведь в случае необходимости отменить операцию управление потоком будет уже передано второму компоненту. А если совершение операции требует длительного времени? На мой взгляд, асинхронные запросы здесь более удобны. Сбрасываем событие получения ответа, отсылаем запрос, а по callback-у с результатом зажигаем эвент. В случае чего, сами устанавливаем событие получения ответа и восстанавливаем контроль над потоком (например, завершаем). Второй компонент в таком случае должен иметь свой собственный поток обработки запросов (хотя бы один), тогда при получении запроса он ставит этот запрос в очередь и зажигает свой эвент, освобождающий поток для обработки запроса. Поток выполняет обработку, вызывает нужный callback, передавая результат, и затем, если запросов больше не поступало, идёт спать в ожидании очередного события. Эта схема позволяет избавиться от частичной неуправляемости потока первого компонента, а также избежать лишних затрат на болтание в бесконечных циклах - каждый из двух потоков спит, пока его не разбудят по необходимости. Всё делается, если грубо, как раз на паре событий: первое событие - это событие завершения обработки запроса в первом компоненте, второе - событие получения запроса для обработки во втором компоненте.
Конечно, рассматриваемый в этой теме учебный пример с управлением крыльями птицы недостаточно нагляден - там придётся, видимо, реализовывать оба потока в рамках одного класса, - но суть схемы от этого особо не изменяется.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #34 : 09-12-2007 12:52 » 

Вад, Все сводится к обработке событий (event). Есть событие разрешения - вперед продолжайте, нету -  сиди и не рыпайся, в крайнем случае, займись чем-нибудь, хоть тетрис собирай.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines