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

黑马程序员_温习 多线程 (个人笔记)

2013-12-13 18:43 190 查看
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

多线程

进程:是一个正在执行的程序

线程:(1)就是进程中一个独立的控制单元

一个进程中至少有一个线程。

(JAVA VM 启动时会有一个进程"java.exe",该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于

mian方法中,称之为主线程。

其实JVM启动时不止一个线程,还有负责垃圾回收的机制线程)

(2)线程有自己的默认名称

Thread-编号,该编号从0开始。通过getName()方法:获取名称

通过setName()方法和构造函数:修改名称

通过static Thread currentThread()方法:获取当前线程对象

特点:随机性(执行权和执行时间都由CPU决定)

原理图:



有两种方式冻结线程:

(1):sleep(time)即规定休眠时间,时间到则进入阻塞(待命)状态,拿到执行权就执行

(2):wait()方法使程序休眠,用notif()方法唤醒线程,若没有执行notif()则线程一直冻结

如何定义线程

|--方法(一):继承Thread类(无法作用同一个run方法)

|--步骤:(1)定义类继承Thread

(2)复写Thread类中的run方法(因为所要执行的代码都在run方法中运行)

(3)调用线程的start方法,该方法有两个作用(1)启动线程(2)调用run方法

例:

class Demo extends Thread//定义类继承Thread,现在此类可以被线程操作

{

public void run()//复写run方法,因为线程只执行run中的代码,所以要复写run方法,把要执行的代码写入run方法中

{

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

System.out.println("Demo=="+x);

}

}

class ThreadDemo

{

public static void main(String[] args)

{

Demo d = new Demo();//建立对象

d.start();//开启线程

d.run();//注意 !!!这个没有开启线程,这个只是调用了Demo对象中的run方法

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

System.out.println("Hello"+x);

}

}

|--方式(二):
实现Runnable接口(可作用于同一个run方法)

|--步骤:
(1)定义类实现Runnable接口

(2)覆盖Runnable接口中的run方法(原因同上,执行内容都在其中)

(3)通过Thread类建立线程对象

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

|--为什么要将Runnable接口的子类对象传递给Thread的构造函数呢?

答:因为自定义的run方法所属的对象时Runnable接口的类对象,

所以要让线程去指定对象的run方法就必须明确run方法的所属对象。

(5)调用Thread类的start方法开启线程并调用runnable接口子类的run方法

例(售票系统):

class Ticket implements Runnable//类实现runnable接口,以便多个线程操作同一个run方法

{

private int tick = 100;

public void run()//复写run方法(因为线程只运行run,故要把执行代码写入run方法)

{

while (true)

{

if(tick>0)

{

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

}

}

}

}

class TicketDemo

{

public static void main(String[] args)

{

Ticket t = new Ticket();//先建立类对象

Thread t1 = new Thread(t);//创建线程并指定线程所要操作的类

Thread t2 = new Thread(t);

Thread t3 = new Thread(t);

Thread t4 = new Thread(t);

t1.start();//开启线程

t2.start();

t3.start();

t4.start();

}

}

实现方式和继承方式有什么区别??

|--区别:继承(Thread)线程代码存放在Thread子类run方法中

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

实现的好处:避免了单继承的局限性,定义线程时建议使用实现方式

如图:


多线程的安全问题

|--原因:当多条语句操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程就参与进来执行,导致共享数据的错误.

解决办法(同步)synchronized

|--对多条操作共享数据的语句,只能让一个线程执行完。在执行过程中,其他线程不可以参与执行。

|--JAVA对多线程的安全问题提供的决绝方式就是(同步代码块)synchronized

|--格式: synchronized(对象)

{

需要被同步的代码

}

|--前提:(1)必须要有两个或两个以上的线程

(2)必须是多个线程使用同一个锁

|--好处:解决了多线程的安全问题

|--弊端:多个线程需要判断所,较为消耗资源

|--同步函数用的是哪一个锁呢

|--非静态:非静态函数需要被对象调用,那么函数都有一个所属对象引用。就是this

所以非静态同步函数使用的锁是this

|--静态:静态函数没有对象,但是一定有该类对应的字节码文件对象。--类名.class

该对象的类型是class所以,静态函数使用的锁是该方法所在类的字节码文件对象

即--类名.class

单例设计模式

|--饿汉式:

class single

{

private static final single s = new Single();

private single(){}

public static Single getInstance()

{

return s;

}

}

|--懒汉式(加同步)

class single

{

private static Single s = null;

private Single(){}

public static Single getInstance()

{

if(s==null)

{

synchronized(Single.class)

{

if(s==null)

s = new Single();

}

}

}

}

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: