黑马程序员技术交流社区
标题:
关于多线程同步的理解
[打印本页]
作者:
何明辉
时间:
2012-7-25 22:44
标题:
关于多线程同步的理解
本帖最后由 何明辉 于 2012-7-27 12:23 编辑
class Common
{
private String name;
private int age;
public static boolean flag=false;
void set(String name ,int age)
{
this.name=name;
this.age=age;
}
String get()
{
return name+"...."+age;
}
}
class In implements Runnable
{
Common com;
In(Common com)
{
this.com=com;
}
public void run()
{
int x=0;
while(true)
{
while(!Common.flag)
{
if(x==0)com.set("HeMingHui",25);
else com.set("HeMingSheng",23);
x=++x%2;
Common.flag=false;
}
}
}
}
class Out implements Runnable
{
Common com;
Out(Common com)
{
this.com=com;
}
public void run()
{
while(true)
{
while(Common.flag)
{
System.out.println(com.get());
Common.flag=true;
}
}
}
}
class InOutDemo1
{
public static void main(String[] args)
{
Common com=new Common();
Thread t1=new Thread(new In(com));
Thread t2=new Thread(new Out(com));
t1.start();
t2.start();
}
}
上面的程序中实现的功能是:线程t1实现输入信息,线程t2输出信息,在dos中实现交替显示。
(1)根据对同步的概念的理解我设计上面的程序也能实现相应的功能啊,线程t1和t2通过对flag值的交替改变也能实现同步啊,怎么没有达到预期的效果。
(2)还有就是我看毕老师第十二天第5集的视频上面列子中,列子里面线程t1,t2,t3,t4中t1和t2都在同步函数里面,也就是没有出来,好比老师说的蹲厕所的列子,只要是在里面,不管碰到是sleep()和wait()都会在里面,那么其他线程就不会进去。所以最后结果要么全部是输入,要么全部是输出。因为毕老师第11天第10集就是这么讲的,如果碰到sleep()就出了同步的话,那么第11天10集里面最后加了同步在碰到sleep()后有可能输出结果还会出现0,-1,-2的情况。请高手帮我纠正误区,谢谢!
作者:
张頔
时间:
2012-7-25 23:03
class Common
{
private String name;
private int age;
public static boolean flag=false;
void set(String name ,int age)
{
this.name=name;
this.age=age;
}
String get()
{
return name+"...."+age;
}
}
class In implements Runnable
{
Common com;
In(Common com)
{
this.com=com;
}
public void run()
{
int x=0;
while(true)
{
while(!Common.flag)
{
if(x==0)com.set("HeMingHui",25);
else com.set("HeMingSheng",23);
x=(++x)%2;//
这个地方你写错了
Common.flag=true;//
这个地方改成Common.flag= true这样他才会进入
//
out的里的run()里第二个while循环
}
}
}
}
class Out implements Runnable
{
Common com;
Out(Common com)
{
this.com=com;
}
public void run()
{
while(true)
{
while(Common.flag)
{
System.out.println(com.get());
Common.flag=false;//
Common.flag的值改为false这样在叫它进入in循环
}
}
}
}
class InOutDemo1
{
public static void main(String[] args)
{
Common com=new Common();
Thread t1=new Thread(new In(com));
Thread t2=new Thread(new Out(com));
t1.start();
t2.start();
}
}
作者:
罗宵
时间:
2012-7-26 09:39
你上面的代码都没有加synchronized()锁,所以肯定不会同步啦。
一般若要线程t1和t2通过对flag值的交替改变也能实现同步,则需要添加wait() notify()方法等待唤醒;我们课件上的例题你看看
public class Student {
public String name;
public int age;
boolean flag = false;
}
* 设置学生值的线程
*/
public class Input implements Runnable {
private Student s;
//Object obj = new Object();
public Input(Student s){
this.s = s;
}
@Override
public void run() {
int x = 0;
while (true) {
synchronized (s) { //t1
//如果有数据,则设置数据这个线程就等待.
if(s.flag){
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (x % 2 == 0) {
s.name = "刘德华";
s.age = 50;
} else {
s.name = "朱丽倩";
s.age = 45;
}
//有数据
s.flag = true;
//改变数据的标记后,唤醒输出线程
s.notify(); //唤醒对方的同时,本身也可能还有执行权.
}
x++;
}
}
}
* 打印学生信息
*/
public class Output implements Runnable {
private Student s;
//Object obj = new Object();
public Output(Student s){
this.s = s;
}
@Override
public void run() {
while (true) {
synchronized (s) { //t2
if(!s.flag){
try {
s.wait();//t2这个线程就bu走了
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name + "***" + s.age);
//没有数据改标识为false
s.flag = false;
//唤醒输入线程
s.notify();
}
}
}
}
public class StudentTest {
public static void main(String[] args) {
//创建学生对象,这是一个资源
Student s = new Student();
Input in = new Input(s);
Output out = new Output(s);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
//t1,t2带过去进行判断
}
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2