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

黑马程序员 多线程

2014-03-16 11:36 211 查看
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

黑马程序员 多线程

一、概念

进程:正在进行的程序

线程:就是进程中一个负责程序执行的控制单元(执行路径),一 个进程中可以多执行路径,称为多线程。

二、利和弊

利:多个程序同时执行

弊:效率低

三、创建线程

1、用Thread类创建线程,步骤:

a、继承Thread类

b、覆写Thread类的run()

c、创建Thread类的子类对象创建线程

d、调用start()开启线程并调用线程的任务run方法执行

实例:

//继承Thread类

public class TestThread extends Thread{

//覆盖Thread类的run()

public void run() {

while(true){

System.out.println(Thread.currentThread().getName()+"is running");

}

}

}

public class TestThread2 {

public static void main(String[] args) {

//调用TestThread类的start()开启线程

new TestThread().start();

while (true) {

System.out.println("main Thread is running");

}

}

}

2、使用Runnable接口创建多线程,步骤:

a、实现Runnable接口,覆写run()

b、创建Runnable类的子类实例

c、创建一个Thread类实例,并将Runnable类的子类实例作为构造参数

d、调用start()开启线程

实例:

//实现Runnable接口

public class TestThread implements Runnable{

//覆写run()

public void run() {

while(true){

System.out.println(Thread.currentThread().getName());

}

}

}

public class TestThread2 {

public static void main(String[] args) {

//创建TestThread类的实例

TestThread tt=new TestThread();

//创建一个Thread类的实例,并将子类实例对象做为构造参数

Thread t=new Thread(tt);

//调用start()开启线程

t.start();

while (true) {

System.out.println("main thread is running");

}

}

}

3、两种实现线程方法的比较(常用实现Runnable接口这种方法)

实现Runnable接口比继承Thread类的优点:

a、将线程的任务从线程的子类中分离出来,进行了单独的封装

b、避免了单继承的局限性

实例:4个窗口同时卖100张票

public class TestThread implements Runnable{

private int tickets=100;

public void run() {

while(true){

if(tickets>0)

System.out.println(Thread.currentThread().getName()+"is saling ticket"+tickets--);

}

}

}

public class WindowThread {

public static void main(String[] args) {

TestThread tt=new TestThread();

new Thread(tt).start();

new Thread(tt).start();

new Thread(tt).start();

new Thread(tt).start();

}

}

四、线程安全

1、线程安全问题原因:多个线程操作同一共享数据,一个线程操 作共享数据中,其它线程参与进来,导致读写错误,线程安全问 产生。

2、解决:同步代码块。(一个线程操作同一共享数据时,其它线 程不能参与进来)

格式:synchronized (对象) {需要被同步的代码;}

3、同步的利和弊:利,解决了线程安全问题;弊,效率降低,都 要判断同步锁。

4、同步的前提:同步中必须有多个线程并使用同一个锁。

5、同步函数:只需在需要同步的函数定义前加上synchronized关键字

6、代码块与函数间的同步:代码块和函数使用同一个监视器对象,函数使用的监视器对象是this。

7、多线程下的单例:

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

}

}

return s;

}

}

同步代码块解决了线程安全问题,多加if判断提高了同步带来的效率低问题

8、死锁问题:原因,同步的嵌套。

五、线程间的通讯

概念:多个线程在处理同一资源,任务却不相同。

实例:

public class Resouce {

private String name;

private String sex;

private boolean flag=false;

public synchronized void set(String name,String sex){

if (flag) 

try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}

this.name=name;

this.sex=sex;

this.flag=true;

this.notify();

}

public synchronized void out(){

if (!flag)

try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}

System.out.println(name+"......."+sex);

this.flag=false;

this.notify();

}

}

public class Input implements Runnable{

Resouce r=null;

public Input(Resouce r) {

this.r=r;

}

 

public void run() {

int i=0;

while (true) {

if (i==0) {

r.set("大牛", "男");

}else{

r.set("lili", "nv");

}

i=(i+1)%2;

}

}

}

public class Output implements Runnable{

Resouce r=null;

public Output(Resouce r) {

this.r=r;

}

public void run() {

while (true) {

r.out();

}

}

}

public class ResouceDemo {

public static void main(String[] args) {

Resouce r=new Resouce();

new Thread(new Input(r)).start();

new Thread(new Output(r)).start();

}

}

注:等待唤醒机制方法:

1、wait():让线程处于冻结状态,被wait的线程存储于线程池中。

2、notify():唤醒线程池中的任意线程。

3、notifyAll():唤醒线程池中的所有线程。

(这些方法都必须定义在同步中)

六、线程的生命控制

停止线程:通过run()中循环条件的方式结束线程通用


---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

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