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

黑马程序员_基础回顾之多线程

2012-07-22 10:59 190 查看
---------------------- android培训java培训、期待与您交流!
----------------------

1:多线程
(1)概述 在一个进程中有多条执行路径.
A:进程 正在执行的程序,它代表着应用程序的执行区域.
B:线程 进程的执行路径.
**如果一个进程中一个一个线程,那么该程序就是单线程程序.
**如果一个进程中有多个线程,那么该程序就是多线程程序.

举例:请人吃饭
    360管理界面中,杀毒,清理垃圾可以同时执行.
    迅雷下载
(2)jvm的启动是多线程的还是单线程的.
A:多线程的.
**为什么

class Demo
{
public static void main(String[] args)
{
System.out.println("hello");
new Demo();
System.out.println("world");
new Demo();
new Demo();
//内存溢出
new Demo();
new Demo();
System.out.println("itcast");
}
}

单线程:程序从main方法开始,从上往下,从左往右,依次执行.
先输出,然后,创建对象,在输出,在创建多个对象.在输出.最后启用垃圾回收.
但是,如果在半路出现了内存溢出.程序就有问题了.
多线程:jvm启动后,最少有两个线程启动了.主线程启动,还有垃圾回收线程启动.

(3)创建线程的方式
A:继承Thread类:一种方法是将类声明为Thread的子类。该子类应重写Thread类的run方法。
**步骤
1:继承Thread步骤
A:定义类继承Thread类.
B:重写Thread类中的run方法.run方法中存储的是多线程要运行的代码.
C:创建Thread类的子类对象.
D:调用start方法开启线程,执行run方法里面的内容.

class MyThread extends Thread

{
public void run()//重写Thread类的run方法。
{
for(int i=0; i<10; i++)
{
for(int j=0; j<1000000000; j++);
System.out.println("***:"+i);
}
}

}

class ThreadDemo

{
public static void main(String[] args) 
{
//创建了线程的对象
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();

//调用线程对象中的普通方法
//t1.run();
//t2.run();

//启动多线程
t1.start();//启动线程t1。

t2.start();//启动线程t2。
}

}

**线程的随机性:在同一时刻,CPU只能执行一个程序,这个多线程的程序其实是CPU告诉切换导致的,为什么这个线程我们没有看到了,因为这个切换的时间很短。千分之一毫秒,有没有真正意义上的多线程了?多个CPU就可以,内存足够大。
**线程的生命周期:

创建:创建一个线程的对象,并对这个对象做了初始化工作。

就绪:这个状态的对象就是有执行资格,没有执行权。

运行:这个时候对象既有执行资格,又有执行权。

阻塞:这个对象释放了执行资格,并释放执行权。

死亡:线程对象结束。

B:实现Runnable接口
**步骤

2:实现Runnable的步骤
A:定义类实现Runnable接口.
B:重写Runnable接口中的run方法.run方法中存储的是多线程要运行的代码.
C:创建Thread类的对象,并创建接口的实现类的对象,作为参数传递给Thread类的对象.
D:调用start方法开启线程,执行run方法里面的内容.

/*
需求:铁路售票,假如现在有100张票,有4个售票口.
分析:对票进行描述.
四个窗口售票互不影响.
因为是4个窗口售票,所以我们要采用多线程技术.
*/

class Ticket implements Runnable//实现Runnable接口

{
private int tickets = 100;
public void run()
{
while(tickets>0)
{
System.out.println(Thread.currentThread().getName()+"***"+(tickets--));
}
}

}

class ThreadDemo6

{
public static void main(String[] args) 
{
Ticket t = new Ticket();
//创建Thread类的对象。并通过有参构造方法把实现了Runnable接口的Tickett类的对象和线程名字传了过去
Thread t1 = new Thread(t,"窗口1");
Thread t2 = new Thread(t,"窗口2");
Thread t3 = new Thread(t,"窗口3");
Thread t4 = new Thread(t,"窗口4");

t1.start();
t2.start();
t3.start();
t4.start();
}

}

问题:考虑,为什么有了Thread类还需要Runnable接口.

我们的类,它本身可以由父类,但是它其中的某些方法需要多线程技术来实现.

这种情况是存在的,Thread它就不能再被这个类继承,所以出现了Runnable接口.

类只能单继承,static修饰的数据生命周期太长.

(4)多线程的安全问题
A:线程访问的延迟
B:线程的随机性

(5)同步解决线程安全问题
A:同步代码块
格式:同步代码块
synchronized(对象)
{
需要同步的代码;
}

同步代码块中的锁可以是任意对象.但是要在成员范围内定义.
在局部的话,会导致锁发生变化,因为你每次执行方法,都会重新创建一个对象.

**同步的前提
1:多个线程操作加同步.
2:使用同一个锁.
**同步的好处 提高了安全性
 同步的弊端 效率较低
安全性和效率是你们一直要考虑的问题,而且很多时候,他们是对立的关系.
B:同步函数:用的锁是this对象锁

---------------------- android培训java培训、期待与您交流!
----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息