黑马程序员——多线程

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一、线程(Thread类)

1、概念

进程:运行中的程序。一个程序在运行期间至少会开启一个进程;

线程:一个进程中可以有多个线程,线程就是程序运行的一条路径。

         CPU在同一时间只能为一条线程工作,CPU在各个线程之间快速切换。

 

多线程下载速度快的原因:N个用户连接服务器,如果一个用户开启多个线程连接服务器,占用服务器的CPU更多的资源,服务器在这个用户的线程上工作的时间越长,下载越快。

2、开启新线程的方法

(1)继承Thread

class MyThread extends Thread {  a.定义一个类继承Thread方法

public void run( ) {   b.重写run方法,将新线程做的事写在run方法中

……}

}

class ThreadDemo {

public static void main(String[] args) {

       MyThread mt = new MyThread( ); c.创建线程对象

       mt.start( );   d.开启新线程对象名.start()”,新线程上自动调用run()方法

}

}

(2)实现Runnable接口

class MyRunnable implements Runnable { a.定义一个类实现Runnable接口

public void run( ) {   b.重写run()方法,将新线程要做的事写在run()方法中

……}

}

class MyRunnableDemo {

public static voidmain(String [] args) {

       MyRunnable mr = new MyRunnable( );c.创建自定义的Runnable子类对象

        Thread t = new Thread(mr);   d.创建Thread对象,将子类对象作为参数

传进Thread的构造函数

       t.start( );                  e.调用start()方法开启新线程

}

}

(3)使用匿名内部类的形式开启新线程

A. 定义Thread的子类对象,调用start( )方法

newThread( ){

    public void run( ) {

           …………

}

}.start();

B. 定义Runnable接口的实现类,作为参数传入Thread的构造函数,调用start()方法

newThread(new Runnable( ) {

public void run( ) {

       ……

}

}).start();

3Thread类的常用方法:

(1) Thread t = Thread.currentThread();   // 获取当前正在执行的线程对象的引用

(2) String getName( )  //获取当前线程的名字

String name = t.getName( ); 

String name = this.getName( );  如果线程对象是Thread类的子类,可写成this

(3)String setName(String name);  //设置线程的名字。线程开始前后都可以设置

A.创建线程时指定名字:Thread t =new Thread(“线程1”);

BThread t = Thread.currentThread( );

   t.setName( );

(4)static void sleep(long millis); //控制当前线程休眠

  Thread.sleep(3000); //让当前正在执行的线程休眠3000毫秒

  注意:a.如果当前类是Thread的子类,可以直接写sleep(3000).

               b. run( )方法不能抛异常,只能抓异常。因为run()方法是重写ThreadRunnable类的,而这两个类没有抛出异常。

(5)void setDaemon(boolean b); // 设置当前线程为守护线程,守护线程不单独执行

  例如:t2.setDaemon(true); t2线程设置为守护线程

(6)t1.join(); // 加入线程。当前线程暂停,等待t1运行结束之后再继续执行。

二、同步

   同步是指多个线程可以同时访问一个对象。多线程并发操作同一对象时,一条线程的访问还没结束,CPU切换到另一条线程工作,导致数据访问异常。

      

任何对象都可以。如果要在主函数中创建多个对象,要实现同步可将锁对象加static关键字

这时我们希望一个线程操作结束之后另一个线程再开始操作,所以需要将代码进行同步。进行同步之后的代码在多个线程中同一时间只能执行一段,即使CPU切换到其他线程也不会执行其他线程的代码

1、同步代码块

  

2、同步方法:

public synchronized void print1() { 同步代码 }

public synchronized void print2() { 同步代码 }

// 使用调用当前方法的对象即this作为锁对象。

  如果想要同步方法和同步代码块同步,使用this作为锁对象。

 

三、多线程通信:必须是在同步代码中

使用锁对象的wait( )方法进行等待。在同步方法中锁对象为this,即this.wait( )

使用锁对象的notify( )方法随即唤醒等待的线程。

使用锁对象的notifyAll( )方法唤醒所有等待的进程。

定义标志变量在线程间切换。 int flag = 1;

四、JDK1.5之后的同步与通信

1、同步

(1)导入包:import java.util.concurrent.locks.ReentrantLock

(2)创建锁对象:ReentrantLock lock = new ReentrantLock( )

(3)上锁:lock.lock( );

(4)解锁:lock.unlock( );

2、通信

(1)导入包:java.util.concurrent.locks.ReentrantLock;

          java.util.concurrent.locks.Condition;

(2)创建锁对象:ReentrantLock lock = new ReentrantLock( );

  使用锁对象的newCondition()方法获取Condition对象:

  Condition c1 =lock.newCondition( );

  Condition c2 =lock.newCondition( );

(3)用不同的Condition对象的await( )方法和signal( )方法控制不同线程的等待和唤醒:

  c1.await();  //线程在c1对象上等待

  c1.signal();  //唤醒在c1对象上等待的线程


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值