黑马程序员——自己学习到的一些Java多线程知识

---------------------- android培训java培训、期待与您交流! ----------------------

大学时java课程只讲了一半,所以多线程对我来说是第一次接触,之前的计算机操作系统里学习了进程,提到了一下线程,是进程中的一个独立运行单元。所谓的线程是指程序的运行流程,而多线程技术是单个程序内部也可以在同一时间执行多个代码段完成不同的任务。Java虚拟机启动后会有一个进程java.exe,其中至少有一个线程负责java程序的执行也就是主线程,当然不只一个线程在运行。

想要自己定义一个线程有两种方法:一种方法是将类声明为Thread子类,该子类重写Thread类的run()方法,将自定义代码存储在run方法中让线程运行。

class A extends Thread

{

public void run()

{

重写的方法体;

}

}

想要使用这个线程要用new A()来创建好一个线程,使用start()方法来启动线程并执行run()方法。而原因是CPU在各线程间快速的切换,其它线程与主线程之间在不停的争夺CPU执行权,所以运行结果是无序的。自定义线程的名称在构造线程对象时传递一个名称通过父类的构造方法命名,使用getName方法取出即可。static currentThread():获取当前线程对象。

第二种方法是声明实现Runnable接口的类,重写runnable接口中的run方法,通过Thread类建立线程对象,将runnable接口的子类对象作为实际参数传递给Thread类的构造函数,调用Thread类的start方法开启线程并调用runnable接口子类的run方法

class B implements Runnable

{

public void run()

{

重写的方法体;

}

}

多线程机制提供了方便,但如果程序一次激活多个线程,并且多个线程共享同一资源时就可能彼此发生冲突。使用线程的同步来解决。同步的前提必须要有两个或者两个以上的线程,而且多个线程使用同一把锁,才能保证同一时间只能有一个线程在运行。同步函数只需要把synchronized放在函数返回值类型之前就可以,但是函数内部只能留下操作有关共享数据的语句,而且使用的锁为this。同步函数可以被静态修饰,与此同时它使用的锁是该方法所在类的字节码文件对象:类名.class。同步出现嵌套时,容易造成死锁

synchronized(对象)

{

需要同步的代码;

}

而线程间通讯其实就是多个线程在操作同一资源,其中很重要的就是等待唤醒机制。等待和唤醒使用同一个锁,等待使用wait()方法,唤醒使用notify(),notifyall()方法。只有同一个锁上的被等待进程可以被同一个锁上notify唤醒,不可以被不同锁的notify唤醒。

停止线程,只要让线程的run方法可以运行结束,线程自然就会结束,所以其中的循环一定要写结束标记。使用interrupt()方法让线程终止,当线程处于被sleep方法调用、被wait方法调用或者I/O阻塞时可以使用interrupt来打破这种阻塞状态,当interrupt()被调用后,会返回一个interruptedException,这时只要在run方法中使用try{}catch{}来捕获异常让线程安全退出。

class  InOutDemo
{
public static void main(String[] args) 
{ //分别创建2个线程来存入和取出
Res r=new Res();
Input in=new Input(r);
Output out=new Output(r);
Thread t1=new Thread(in);
Thread t2=new Thread(out);
t1.start();
t2.start();
}
}
class Res//自定义一个资源类,设置其属性
{
String name;
String sex;
boolean flag;
Res()
{
this.name=name;
this.sex=sex;
flag=true;
}
}
class Input implements Runnable   //定义一个添加类,判断资源的标志位flag来确定是否添加
{
private Res r;
Object obj=new Object();
Input(Res r)
{
this.r=r;
}
public void run()
{
int x=0;
while(true)
{
synchronized(r)//同步代码块,使用的锁为资源对象
{
if(r.flag)//判断标志位决定是否wait?
try{r.wait();}catch(Exception e){}
if(x==0)
{ r.name="Jim";
r.sex="man";
}else
{
r.name="杖娘";
r.sex="女";
}
x=(x+1)%2;
r.flag=true;
r.notify();//唤醒其他线程运行
}
}
}
}
class Output implements Runnable //定义一个取出类,依旧是判断资源对象的标志位
{
private Res r;
Output(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
synchronized(r)//和前一个同步代码块使用同一把锁
{
if(!r.flag)
try{r.wait();}catch(Exception e){}
System.out.println(r.name+"....."+r.sex);
r.flag=false;
r.notify();
}
}
}
}



---------------------- android培训java培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net/heima
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值