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

黑马程序员 JAVA基础<三> 多线程

2013-06-08 00:48 579 查看
-------
android培训java培训、期待与您交流! ----------



1:多线程

(1)线程:线程是进行的执行单元,执行路径。

进程:就是正在运行的程序。一块正在被使用的内存区域。

如果一个应用程序的执行只有一条执行路径,被称为单线程程序。

如果一个应用程序的执行有多条执行路径,被称为多线程程序。

举例:

迅雷下载,360管理界面,班长请吃饭,去医院体检

(2)JVM的启动是多线程的吗?

是。因为如果JVM启动只启动了main线程的话,那么,在程序的执行过程中,

有可能会引发内存溢出,而java很少看到这种情况,为什么呢,就是因为,

java的垃圾回收线程一直也在运行,当内存不够的情况,会自动去扫描内存中

是否有垃圾存在,有就立马清除。

这样来说,最低有两个线程启动了。所以,JVM的启动是多线程的。

(3)自己如何模拟多线程程序

A:继承Thread类

步骤:

a:创建一个类,继承Thread类

b:重写run方法

c:创建类对象,调用start方法

代码体现:

public class ThreadDemo extends Thread

{

@Override

public void run()

{

for(int x=0; x<100; x++)

{

System.out.println(getName()+"***"+x);

}

}

}

public class ThreadDemoTest

{

public static void main(String[] args)

{

ThreadDemo td1 = new ThreadDemo("刘备");

ThreadDemo td2 = new ThreadDemo("孙权");

td1.start();

td2.start();

}

}

B:实现Runnable接口

步骤:

a:创建一个类,实现Runnable接口

b:重写run方法

c:创建Thread类对象,创建Runnable子类对象,把Runnable的子类

对象作为构造参数传递给Thread的构造方法

d:调用start方法

代码体现:

public class RunnableDemo implements Runnable

{

@Override

public void run()

{

for(int x=0; x<100; x++)

{

System.out.println(Thread.currentThread().getName()+"***"+x);

}

}

}

public class ThreadDemoTest

{

public static void main(String[] args)

{

RunnableDemo rd = new RunnableDemo();

Thread td1 = new Thread(rd,"林青霞");

Thread td2 = new Thread(rd,"刘意");

td1.start();

td2.start();

}

}

(4)实现多线程的方式有几种,分别怎么实现?

(5)启动线程调用的是哪个方法,它做了什么事情?

启动线程调用的是start()方法。

它启动线程,并且自动调用了run()方法。

start()和run()的区别?

(6)线程的生命周期及每个状态的特点。

新建:创建线程对象

就绪:具有执行资格,没有执行权

运行:具有执行资格,有执行权

阻塞:没有执行资格,没有执行权

死亡:对象变成垃圾

内存体现:



(7)下午通过卖票程序演示出线程安全问题。

A:线程安全是怎么产生的?

线程的随机性

线程的延迟性

B:如何判断某段代码有没有线程安全问题呢?

a:有没有共享数据

b:看是否有多条语句操作共享数据

c:看是否有多个线程进行操作

c:如何解决线程安全问题?

a:同步代码块

synchronized(对象)

{

需要被同步的代码。

}

对象:可以是任意对象。

b:同步方法

在方法上添加synchronized关键字即可

锁对象:this

注意:静态方法的锁对象 当前类的字节码文件对象。

类名.class

D:同步前提

a:两个以上的线程操作的时候

b:对这多个线程加同步必须使用的是同一把锁

E:同步弊端

每次程序的执行都会去判断锁对象,消耗了资源,降低了效率。

线程安全,效率低。

线程不安全,效率高。

开发中的一个难题:要么效率,要么安全。

(8)卖票程序

public class Ticket implements Runnable

{

//定义100张票

private int tickets = 100;

@Override

public void run()

{

while(true)

{

synchronized(this){

if(tickets>0)

{

try{

Thread.sleep(10);

}catch(InterruptedException e){

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"正在卖出第"+(tickets--)+"张票");

}

}

}

}

}

public class Test

{

public static void main(String[] args)

{

Ticket t = new Ticket();

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();

}

}

(9)单例设计模式的懒汉式,请问他有没有线程安全问题

public class Student

{

private Student(){}

private static Student s = null;

public synchronized static Student getStudent()

{

//t1,t2,t3

if(s==null)

{

//t1,t2,t3

s = new Student();

//t1线程首先创建了一个对象

//t2线程继续创建了一个对象

//t3线程又创建了一个对象

}

return s;

}

}

A:延迟加载

B:线程安全问题

//开发中,用饿汉式即可。

public class Student

{

private Student(){}

private static Student s = new Student();

public static Student getStudent()

{

return s;

}

}

线程范围内的共享数据:在同一个线程数据共享,但在不同线程,数据不共享。

代码体现:

private static int date = 0;//共享数据

public static void main(String[] args) {

for( int i=0;i<=1;i++){

new Thread(new Runnable(){

@Override

public void run() {

date = new Random().nextInt();

System.out.println("***"+Thread.currentThread().getName()+"***"+date);

new A().get();

new B().get();

}

}).start();

}

}

static class A{

public void get(){

System.out.println("A***"+Thread.currentThread().getName()+"***"+date);

}

}

static class B{

public void get(){

System.out.println("B***"+Thread.currentThread().getName()+"***"+date);

}

}

}

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