目录
线程(上)
1. 线程的创建方式
An application that creates an instance of Thread must provide the code that will run in that thread. There are two ways to do this:创建Thread 实例的应用程序必须提供将在该线程中运行的代码。 有两种方法可以做到这一点:-Provide a Runnable object. The Runnable interface defines a single method, run, meant to contain the code executed in the thread.-提供可运行的对象。 Runnable 接口定义了一个方法 run ,旨在包含在线程中执行的代码。-Subclass Thread. The Thread class itself implements Runnable, though its run method does nothing.-子类线程。 Thread 类本身实现了 Runnable ,尽管它的 run 方法不执行任何操作。
Thread类常用构造方法
public Thread (); // 创建一个线程public Thread ( String name ); // 创建一个依据名称的线程public Thread ( Runnable target ); // 根据给定的线程任务创建一个线程public Thread ( Runnable target , String name ); // 根据给定的线程任务和名称创建一个线程
Thread类常用成员方法
public synchronized void start (); // 启动线程但不一定会执行public final String getName (); // 获取线程名称public final synchronized void setName ( String name ); // 设置线程的名称public final void setPriority ( int newPriority ); // 设置线程的优先级public final int getPriority (); // 获取线程的优先级public final void join () throws InterruptedException ; // 等待线程执行完成// 等待线程执行给定的时间 ( 单位毫秒 )public final synchronized void join ( long millis ) throwsInterruptedException ;// 等待线程执行给定的时间 ( 单位毫秒、纳秒 )public final synchronized void join ( long millis , int nanos ) throwsInterruptedException ;public long getId (); // 获取线程的 IDpublic State getState (); // 获取线程的状态public boolean isInterrupted (); // 检测线程是否被打断public void interrupt (); // 打断线程
Thread类常用静态方法
public static native Thread currentThread (); // 获取当前运行的线程public static boolean interrupted (); // 检测当前运行的线程是否被打断public static native void yield (); // 暂停当前运行的线程,然后再与其他线程争抢资源,称为线程礼让// 使当前线程睡眠给定的时间(单位毫秒)public static native void sleep ( long millis ) throws InterruptedException ;// 使当前线程睡眠给定的时间(单位毫秒、纳秒)public static void sleep ( long millis , int nanos ) throwsInterruptedException ;
示例
public class CreateDemo {public static void main ( String [] args ) {Thread t1 = new SubThread ( "inherit" ); // 通过继承实现的线程Thread t2 = new Thread ( new ThreadTask (), "interface" ); // 通过实现Runnable接口实现的线程t1 . start (); //start 方法只是告诉 JVM 线程 t1 已经准备好了,随时可以调度执行try {t1 . join (); // 等待线程 t1 执行完成t1 . join ( 1000 ); // 等待线程 t1 执行 1 秒// 1毫秒 = 1000微秒 = 1000000 纳秒t1 . join ( 1000 , 50000 ); // 等待线程 t1 执行 1.5 秒} catch ( InterruptedException e ) {e . printStackTrace ();}t2 . start ();}static class SubThread extends Thread {public SubThread () {}public SubThread ( String name ) {super ( name );}@Overridepublic void run () {try {Thread . sleep ( 2000 );} catch ( InterruptedException e ) {e . printStackTrace ();}System . out . println ( getName () + "=>This is SubThread" );}}static class ThreadTask implements Runnable {@Overridepublic void run () {Thread thread = Thread . currentThread ();String name = thread . getName ();System . out . println ( name + "=>This is Implementation" );}}}
总结
创建线程有两种方式:实现 Runable
接口和继承
Thread
。相较于继承
Thread
,实现
Runable
接口更具有优势,在实现接口的同时还可以继承自其他的父类,避免了Java
中类单继承的局限性;同时Runable 接口的实现可以被多个线程重用,但继承
Thread
无法做到;后续学到的线程池中支持Runable 接口但不支持
Thread
2. 线程内存模型
3.线程安全
案例
某火车站有 10 张火车票在 3 个窗口售卖
代码实现
public class SaleThreadTest {public static void main ( String [] args ) {SaleTask task = new SaleTask ();Thread t1 = new Thread ( task , " 窗口 1" );Thread t2 = new Thread ( task , " 窗口 2" );Thread t3 = new Thread ( task , " 窗口 3" );t1 . start ();t2 . start ();t3 . start ();}static class SaleTask implements Runnable {private int totalTickets = 10 ; // 售卖 10 张火车票@Overridepublic void run () {while ( true ){String name = Thread . currentThread (). getName ();System . out . println ( name + " 售卖火车票: " + totalTickets );totalTickets -- ;if ( totalTickets <= 0 ) break ;try {Thread . sleep ( 100L );} catch ( InterruptedException e ) {e . printStackTrace ();}}}}}
执行结果
从结果中可以看出,同一张火车票被卖了多次,这是由于线程之间获取信息不同步导致。