您的位置:首页 > 职场人生

黑马程序员 java基础之多线程

2013-05-14 22:04 337 查看
/*

多线程技术

java虚拟机允许程序并发地运行多个线程。

JVM启动至少有两个线程,一个是主线程(代码在mian方法中);另一个是负责垃圾回收机制的线程。

创建线程

方法一

在java.lang包中有一个Thread类

继承Thread类

步骤:

1,定义类继承Thread.

2,复写Threa类中的run方法;

目的:将自定义代码存储在run方法中,让线程运行。

3,调用start(),该方法有两个作用,就是启动线程,调用run方法。

*/

// 例:三个窗口分别买票,每一个窗口卖10张票

class ThreadDemo extends Thread //定义类继承Thread.

{

public void run() //复习run方法

{

int x=1;

while(x<=10)

{

System.out.println(Thread.currentThread().getName()+"....."+x);//打印正在运行的线程

x++;

}

}

}

class Test

{

public static void main(String[] String)

{

new ThreadDemo().start();//创建第一个线程并运行

new ThreadDemo().start();//创建第二个线程并运行

new ThreadDemo().start();//创建第三个线程并运行

}

}

//要点:run方法用于存放线程要运行的代码。

/*

方法二:通过实现Runable接口

步骤:

1,定义类实现(implements)Runnable接口;

2,覆盖Runnable接口的run()方法

3,通过Thread类建立线程对象。

4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

5,调用Thread类的start方法开启线程并调用Runnable的run方法。

实现方式与继承方式的区别

继承Thread:线程代码存放在Thread子类的run方法中。

实现Runnable:线程代码存放在Runnable接口子类的run方法中。

*/

//例如:购票小程序

//有100张票三个窗口卖。三个窗口共享100张票。

class ThreadDemo2 implements Runnable//定义类实现(implements)Runnable接口;

{

private int tick=10;

public void run()//覆盖Runnable接口的run()方法

{

while(true)

{

if(tick>0)

{

//为了问题看起来明显一点在此睡上10毫秒,10好秒后自动回到可执行状态

try{Thread.sleep(100);} catch(Exception e){}

System.out.println(Thread.currentThread().getName()+"......."+tick--);

}

}

}

}

class Test2

{

public static void main(String[] args)

{

ThreadDemo2 th=new ThreadDemo2();//创建ThreadDemo2对象,

new Thread(th).start();//将th作为参数传递给Thread创建线程对象

new Thread(th).start();//同上

new Thread(th).start();//同上

}

}

//以上程序是不安全的,存在线程安全性问题。此多线程操做的是共享数据,因为一个线程对多条语句只执行了一部分,还没完,这时另一个线程进来执行

//导致共享数据错误。

/*

线程的周期

一个线程有4种状态,任何一个线程肯定处于这4中状态中的一种。

1,初始状态(New):当线程对象被建立之后,并在调用start()方法之前。此时线程处于初始状态。

这时线程对象已经产生,但是没被启动。此时可调用start()启动线程和stop()方法停止线程。

2,可执行状态(Runnable):当线程对象调用start方法后,线程就转入可执行状态。当有多个线程处于可执行状态时,

这些线程都一个线程池中,排程器会按照先后顺序排列它们,当有CPU资源时,排程器会依次启动这些线程。

所以,处于可执行状态的线程可能在它正在执行,也可能在线程池中等待。

3,阻塞状态(NonRunnable):如线程对象调用wait()方法后,线程就处于阻塞状态。

此时排程器会忽略它,不对它进行排程。由阻塞状态可以通过resume()方法恢复多可执行状态,它有可能重新执行。

4,退出状态(Done):当一个线程正常结束或调用stop()方法。这个线程就退出了。

控制线程周期的方法

strat() 开启一个线程,由New状态Runnable状态

stop() 结束一个线程,由初始状态或可执行状态转入Done状态。

sleep(long) 线程暂停一段时间。由Runnable状态转入NonRunnable状态,时间到自动返回可执行状态。

wait() 停止正在运行的线程,由Runnable状态转入NonRunnable状态。需要notify()唤醒。

notify();唤醒由wait()停止的线程。

notifyAll() 唤醒所有等待的线程。

suspend() 挂起执行,由Runnable状态转入NonRunnable状态。

resume() 恢复执行,由NonRunnable状态转入Runnable状态。

yield() 明确放弃执行。线程由Runnable状态转入Runnable状态。

多线程的安全性问题

当多线程在操作共享数据是,就会出现安全性问题。因为一个线程对多条语句只执行了一部分,还没完,这时另一个线程进来执行

导致共享数据错误。

解决办法就是:同步代码块。

同步代码块原理:当多线程操作共享数据时,一个线程执行完,才让另一个线程进来执行。

格式:

synchronized(对象) 此对象可以是任意的

{

需要被执行的代码(被多线程操作的共享数据)

}

同步代码块中对象如同锁,就是当一个线程执行到操作同步代码时,就把它锁住,不让其他的线程进入执行。

当此线程执行操作完时,就释放锁。这时其他的线程才可以继续执行同步代码。

同步的前提:

1,必须有两个以上的线程

3,多线程必须使用同一个锁

同步的好处:解决了多线程的安全性问题

同步的弊端:较为消耗资源

同步函数

同步函数只需要在方法前加synchronized修饰即可

同步非静态方法的锁是 this

而同步静态方法的锁是 类名.Class() 因为静态进入内有存时,还没本类对象,只有该类对应的字节码文件对象。

*/

//解决上述程序的线程安全性问题。

//代码如下:

class ThreadDemo3 implements Runnable

{

private int tick=10;

//复写Runnable接口的run方法

public void run()

{

while(true)

{

//让线程暂停一会儿后自动回去可执行状态

try{Thread.sleep(100);}catch(Exception e){}

synchronized(new Object())

{

if(tick>0)

{

System.out.println(Thread.currentThread().getName()+"...."+tick--);

}

}

}

}

}

class Test3

{

public static void main(String[] args)

{

ThreadDemo3 th=new ThreadDemo3();

new Thread(th).start();

new Thread(th).start();

new Thread(th).start();

}

}

/*

死锁

通常死锁的出现是因为 同步嵌套同步时,锁却不同,

*/

class Test implements Runnable

{

private boolean flag;

static Object locka=new Object();

static Object lockb=new Object();

Test(boolean flag)

{

this.flag=flag;

}

public void run()

{

while(true)

{

if(flag)

{

synchronized(locka)//同步用locka锁

{

System.out.println("if locka");

synchronized(lockb)//嵌套同步用lockb锁

{

System.out.println("if lockb"); }

}

}

else

{

synchronized(lockb)//同步用lockb锁

{

System.out.println("else lockb");

synchronized(locka)//嵌套同步用locka锁

{

System.out.println("else locka");

}

}

}

}

}

}

class DeadLockDemo

{

public static void main(String[] args)

{

new Thread(new Test(true)).start();

new Thread(new Test(false)).start();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: