- 创建线程三种方法:
/** * 线程创建方法1:创建线程类 * 1、创建线程类,继承Thread并重写 run() 方法 * 2、创建对象实例,调用对象 start() 方法来启动线程 */ public class CreateTest1 { public static void main(String[] args) { Rabbit rab = new Rabbit(); Tortoise tor = new Tortoise(); rab.start(); tor.start(); for(int i=0;i<1000;i++){ System.out.println("main==>"+i); } } } class Rabbit extends Thread{ @Override public void run(){ for(int i=0;i<50;i++){ System.out.println("兔子跑了 "+i+" 步"); } } } class Tortoise extends Thread{ @Override public void run(){ for(int i=0;i<50;i++){ System.out.println("乌龟跑了 "+i+" 步"); } } }
/** * 线程创建方法2:继承Runnable接口 * 1、创建类并继承Runnable接口,重写 run() 方法 * 2、通过 Thread 生成代理类 * 3、调用代理类的 start() 方法启动线程 */ public class CreateTest2 { public static void main(String[] args) { Work1 w1 = new Work1(); Work2 w2 = new Work2(); Thread t1 = new Thread(w1); Thread t2 = new Thread(w2); t1.start(); t2.start(); for(int i=0;i<1000;i++){ System.out.println("main...."); } } } class Work1 implements Runnable{ @Override public void run() { for(int i=0;i<1000;i++){ System.out.println("一边聊QQ...."); } } } class Work2 implements Runnable{ @Override public void run() { for(int i=0;i<1000;i++){ System.out.println("一边敲hello world...."); } } }
/** * 线程创建方法3:匿名内部类 * 1、创建 Thread 类并重写 run() 方法 * 3、调用 start() 方法启动线程 */ public class CreateTest3 { public static void main(String[] args) { Thread t1 = new Thread(){ @Override public void run() { for(int i=0;i<1000;i++){ System.out.println("匿名...."); } } }; t1.start(); for(int i=0;i<1000;i++){ System.out.println("main...."); } } }
推荐使用继承 Runnable 方法创建线程
/** * 推荐使用继承 Runnable 方法创建线程 * 1、避免单继承局限性 * 2、便于共享资源 * * 模仿买票,票为共享资源,多线程操作同一资源 */ public class CreateTest4 { public static void main(String[] args) { Web12306 web = new Web12306(); Thread t1 = new Thread(web,"路人甲"); Thread t2 = new Thread(web,"黄牛乙"); Thread t3 = new Thread(web,"工程狮"); t1.start(); t2.start(); t3.start(); } } class Web12306 implements Runnable{ private int num = 50; @Override public void run() { while(true){ if(num<=0){ break; } System.out.println(Thread.currentThread().getName()+"抢到了"+num--); } } }
- 线程状态方法
/** * 线程阻塞 * t1.join(); * 阻塞本线程,t1执行完后再执行本线程 * 相当于将本线程追加到t1后(合并线程) */ public class JoinDemo01 extends Thread{ public static void main(String arg[]) throws InterruptedException{ JoinDemo01 demo1 = new JoinDemo01("t1"); JoinDemo01 demo2 = new JoinDemo01("t2"); Thread t1 = new Thread(demo1); Thread t2 = new Thread(demo2); t1.start(); t2.start(); for(int i=0;i<1000;i++){ if(100==i){ t1.join();//main阻塞,t执行完后main再执行(阻塞当前线程,并将当前线程追加到t1后) } System.out.println("main"+i+" .... "); } } private String name; public JoinDemo01(String name){ this.name = name; } @Override public void run() { for(int i=0;i<2000;i++){ System.out.println("["+name+"]"+i+" .... .... "); } } }
/** * 线程等待 * Thread.sleep(1000); * 该线程进入等待状态,不释放锁,小心死锁 */ public class SleepDemo01 { public static void main(String[] args) throws InterruptedException { Date d1 = new Date(); System.out.println(new SimpleDateFormat("mm:ss SS").format(d1)); Thread.sleep(1000); d1 = new Date(); System.out.println(new SimpleDateFormat("mm:ss SS").format(d1)); } }
/** * 线程暂停 * Thread.yield(); * 暂停本线程,但是并不确保一定会运行其他线程 * 如果cpu再次调度到本线程则会继续执行本线程 */ public class YieldDemo01 extends Thread{ public static void main(String[] args) { YieldDemo01 y1 = new YieldDemo01(); Thread t1 = new Thread(y1); t1.start(); for(int i=0;i<100;i++){ System.out.println("main...."+i+"["+i%20+"]"); if(i%20==0){ System.out.println("y"); Thread.yield();//暂停本线程 main } } } @Override public void run() { for(int i=0;i<1000;i++){ try { Thread.sleep(0, 1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("yield...."+i); } } }
- 线程同步
/** * 线程同步(安全、效率低) * synchronized关键字主要是锁定资源 * synchronized关键字修饰的资源有线程访问,则该资源对于其他线程的状态就为锁定状态 * 该线程执行完synchronized修饰的代码块后,该资源解除锁定状态 * 其他线程如果访问被锁定的资源,则会等待,等待该资源解除锁定状态 */ public class SynDemo01 { public static void main(String[] args) { MyJvm mj = new MyJvm(); Thread t1 = new Thread(mj,"张三"); Thread t2 = new Thread(mj,"老王"); t1.start(); t2.start(); } } class MyJvm implements Runnable{ @Override public void run() { synchronized(MyJvm.class){ for(int i=0;i<1;i++){ System.out.println(Thread.currentThread().getName()+" 线程执行开始 "); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0;i<1;i++){ System.out.println(Thread.currentThread().getName()+" 线程执行结束 "); } } } }
- 线程属性
/** * 线程中的属性 * Thread.currentThread() --> 当前线程 * setName()/getName() --> 设置/获取 线程名称(默认为'Thread-'+线程个数) * isAlive() --> 判断线程状态是否处于活动状态 * * setPriority() --> 设置线程优先级 * 该优先级只是概率,并不是绝对优先级 * MAX_PRIORITY 10 * NORM_PRIORITY 5 (默认) * MIN_PRIORITY 1 */ public class InfoDemo01 { public static void main(String[] args) throws InterruptedException { InfoThread it = new InfoThread(); Thread t = new Thread(it,"挨踢"); t.setPriority(Thread.MAX_PRIORITY); t.start(); System.out.println("启动后的状态:"+t.isAlive()); Thread.sleep(1000); it.stop(); Thread.sleep(1000); System.out.println("停止后的状态:"+t.isAlive()); } } class InfoThread implements Runnable{ private boolean flag = true; private int num =0; @Override public void run() { while(flag){ System.out.println(Thread.currentThread().getName()+" --> "+num++); } } public void stop(){ this.flag = false; } }
- 定时器
/** * 定时执行线程 * 1、创建定时器和定时任务(Timer、TimerTask) * 2、将定时任务添加到定时器中并启动定时器 * 3、任务执行完以后,如不需要应终止定时器 * * Timer.schedule(TimerTask,Date,long) * 执行任务,在 Date 时间点执行 TimerTask 任务 ,每隔 long 执行一次(可选) */ public class ScheduleDemo01 { public static void main(String[] args) { Timer timer = new Timer(); TimerTask task = new TimerTask(){ @Override public void run() { System.out.println("任务执行开始...."); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务执行结束...."); } }; timer.schedule(task,new Date()); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); } }
- 创建可以获取返回值的线程
/** * juc中的Callable接口 * 使主线程可以获得其他线程运行后的返回值 * * 1、创建线程池 * 2、通过线程池启动线程,并记录返回结果 * 3、停止服务 */ public class CallableTest1 { public static void main(String[] args) throws InterruptedException, ExecutionException { //创建线程池 ExecutorService ser = Executors.newFixedThreadPool(2); Race rabbit = new Race("小兔子",500); Race tortoise = new Race("老不死",1000); //启动线程、获取值 Future<Integer> result1 =ser.submit(rabbit); Future<Integer> result2 =ser.submit(tortoise); Thread.sleep(3000); rabbit.setFlag(false); tortoise.setFlag(false); int num1 = result1.get(); int num2 = result2.get(); ser.shutdownNow(); System.out.println("兔子跑了 --> "+num1+"步"); System.out.println("乌龟跑了 --> "+num2+"步"); } } class Race implements Callable<Integer>{ private String name; //名字 private long time; //延时时间 private boolean flag=true; private int step; //所走步数 public Race(String name,long time) { super(); this.name = name; this.time =time; } @Override public Integer call() throws Exception { while(flag){ Thread.sleep(time); //延时 step++; } return step; } public String getName() { return name; } public void setFlag(boolean flag) { this.flag = flag; } }