线程-01

1. 程序、进程、线程的理解
程序 (program): 一段静态的代码, 为完成特定任务、用某种语言编写的一组指令的集合。
进程 (process): 程序的一次执行过程,或是 正在运行的一个程序
线程 (thread): 进程可进一步细化为线程,是一个程序内部的一条执行路经。

2. 创建多线程的四种方式
方式一:继承 Thread 类的方式:
* 1. 提供一个继承于 Thread 类的子类
 * 2. 重写 Thread 类的 run(): 将创建的线程要执行的操作,声明在 run() 中。
 * 3. 实例化 Thread 子类
 * 4. 调用子类对象的 start(): 启动线程 调用当前线程的 run()
 
说明两个问题:
1. 能不能直接调用 run() ,去启动分线程?不能!
2. 如何启动第二个分线程,必须重新创建一个 Thread 子类对象,不能使用原有的第一个 Thread 对象再次 start()
 
方式二:实现 Runnable 接口的方式:
* 1. 创建一个实现 Runnable 接口的类
 * 2. 实现 Runnable 中的 run()
 * 3. 创建当前实现类的对象
 * 4. 将此对象作为参数传递到 Thread 类的构造器中,创建 Thread 类的对象
 * 5. 通过 Thread 类的对象调用其 start()
 
 
两种方式的对比:
 * 1. 联系: public class Thread implements Runnable
 * 2. 相同点:启动线程,使用的是同一个 start() 方法
 *
 * 3. 对比:实现 Runnable 接口更好一些。
 *     原因: 1 不影响类的继承。因为类是单继承的。
 *           2 针对于共享数据的操作,更适合使用 Runnable 的方式。
 * 换句话说,实现 Runnable 接口的方式,实现了代码和数据的分离。
 
*************************
方式三:实现 Callable 接口 jdk1.5 以后)
class MyThread03 implements Callable<Integer> {
@Override
public Integer call () throws Exception {
   System. out .println( "-----MyThread03" );
   return 200;
}
}
main(){
FutureTask futureTask = new FutureTask( new MyThread03()) ;
    new Thread( futureTask ).start();
}
 
优点: 分线程执行的方法,可以有返回值 执行的方法可以抛出异常的。
方式四: 使用线程池
// 创建并使用多线程的第四种方法:使用线程池
class MyThread implements Runnable {
@Override
public void run() {
   for ( int i = 1; i <= 100; i ++) {
      System. out .println(Thread. currentThread ().getName() + ":" + i );
   }
}
}
public class ThreadPool {
public static void main(String[] args ) {
   //1. 调用 Executors newFixedThreadPool(), 返回指定线程数量的 ExecutorService
   ExecutorService pool = Executors. newFixedThreadPool (10);
   //2. Runnable 实现类的对象作为形参传递给 ExecutorService submit() 方法中,开启线程
   // 并执行相关的 run()
   pool .submit( new MyThread()); // 线程 .start()
      pool .submit( new MyThread());
   pool .submit( new MyThread());
   //3. 结束线程的使用
   pool .shutdown();
   }
}
3. Thread 类中的常用方法
1.run():Thread 的子类一定要重写的方法。将此分线程要执行的操作,声明在 run()
* 2.start(): 要想启动一个分线程,就需要调用 start():① 启动线程 调用线程的 run()
* 3.currentThread(): 静态方法,获取当前的线程
* 4.getName(): 获取当前线程的名字
* 5.setName(String name) :设置当前线程的名字
* 6.yield(): 当前线程调用此方法,释放 CPU 的执行权
* 7.join(): 在线程 a 中调用线程 b join() 方法 : 只用当线程 b 执行结束以后,线程 a 结束阻塞状态,继续执行。
* 8.sleep(long millitimes ): 让当前的线程睡眠 millitimes 毫秒
* 9.isAlive(): 判断当前线程是否存活
 * 10. 线程的优先级:
 *    MAX_PRIORITY 10
 *    NORM_PRIORITY 5 --- 默认优先级
 *    MIN_PRIORITY 1
 *
 *   设置优先级: setPriority( int priority);
 *   获取优先级: getPriority();
 *  
 *   设置优先级以后,对高优先级,使用优先调度的抢占式策略,抢占低优先级的执行。但是并不意味着高优先级的线程一定先于低优先级的线程执行,而是从概率上来讲,概率更大而已。
 
*************************************
 * 线程通信: wait() / notify() / notifyAll()  ----> java.lang.Object 类中定义的方法
4. Thread 的生命周期

5. 死锁问题
1 . 死锁的理解:
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
2 . 说明: 死锁,是我们开发中需要规避的!
3 . 举例:
public class DeadLockTest {
   public static void main(String[] args ) {
      StringBuffer s1 = new StringBuffer();
      StringBuffer s2 = new StringBuffer();
      new Thread( new Runnable() {
        public void run() {
           synchronized ( s1 ) {
              s1 .append( "a" ); // 类似 s += "a"
              s2 .append( "1" );
              try {
                 Thread. sleep (10);
              } catch (InterruptedException e ) {
                 e .printStackTrace();
              }
              synchronized ( s2 ) {
 
                 s1 .append( "b" );
                 s2 .append( "2" );
                 System. out .println( s1 );
                 System. out .println( s2 );
              }
           }
        }
      }).start();
      new Thread( new Runnable() {
        public void run() {
           synchronized ( s2 ) {
              s1 .append( "c" ); // 类似 s += "a"
              s2 .append( "3" );
              try {
                 Thread. sleep (10);
              } catch (InterruptedException e ) {
                 e .printStackTrace();
              }
              synchronized ( s1 ) {
                 s1 .append( "d" );
                 s2 .append( "4" );
 
                 System. out .println( s1 );
                 System. out .println( s2 );
              }
           }
        }
      }).start();
   }
}
7.sleep()wait()的区别
 * 1.方法声明在哪? Thread:sleep()   Object:wait()
 * 2.共同点:使得当前线程进入阻塞状态
 * 3.使用的范围要求:sleep()使用没情境的要求;wait()必须使用在同步代码块或同步方法中
 * 4.都使用在同步当中的话:wait()需要唤醒:notify()/notifyAll();  sleep():不会释放锁;wait()会释放锁
* 5.sleep是static方法,而wait是成员方法,

猜你喜欢

转载自blog.csdn.net/wojiao228925661/article/details/80678146
今日推荐