java基础---线程
(一)
一、程序 进程 线程
1、程序:指令集 静态概念
2、进程:操作系统 调度程序 动态概念
3、线程:在进程内多条执行路径
(二)
一、继承Thread + run()
启动: 创建子类对象 +对象.start()
package com.zwj.thread; /*** 模拟龟兔赛跑1、创建多线程 继承 Thread +重写run(线程体)2、使用线程: 创建子类对象 + 对象.start() 线程启动* * @author Administrator**/ public class Rabbit extends Thread {@Overridepublic void run() {//线程体for(int i=0;i<10;i++){System.out.println("兔子跑了"+i+"步");}}} class Tortoise extends Thread {@Overridepublic void run() {//线程体for(int i=0;i<10;i++){System.out.println("乌龟跑了"+i+"步");}}}
Rabbit
package com.zwj.thread; public class RabbitApp {/*** @param args*/public static void main(String[] args) {//创建子类对象Rabbit rab = new Rabbit();Tortoise tor =new Tortoise();//调用start 方法rab.start(); //不要调用run方法//rab.run(); tor.start();//tor.run();for(int i=0;i<10;i++){System.out.println("main==>"+i);}}} /* 乌龟跑了0步 乌龟跑了1步 兔子跑了0步 乌龟跑了2步 main==>1 乌龟跑了3步 兔子跑了1步 乌龟跑了4步 main==>2 乌龟跑了5步 兔子跑了2步 乌龟跑了6步 main==>3 乌龟跑了7步 兔子跑了3步 乌龟跑了8步 main==>4 乌龟跑了9步 兔子跑了4步 兔子跑了5步 兔子跑了6步 main==>5 兔子跑了7步 main==>6 兔子跑了8步 main==>7 兔子跑了9步 main==>8 main==>9*/
RabbitApp
二、实现Runnable +run()
启动:使用静态代理
1、创建真实角色
2、创建代理角色 Thread+引用
3、代理角色.start()
推荐使用接口:
1、避免单继承局限性
2、便于共享资源
package com.zwj.thread; /**推荐 Runnable 创建线程1)、避免单继承的局限性2)、便于共享资源使用 Runnable 创建线程1、类 实现 Runnable接口 +重写 run() -->真实角色类2、启动多线程 使用静态代理1)、创建真实角色2)、创建代理角色 +真实角色引用3)、调用 .start() 启动线程* @author Administrator**/ public class Programmer implements Runnable {@Overridepublic void run() {for(int i=0;i<1000;i++){System.out.println("一边敲helloworld....");}}}
Programmer
package com.zwj.thread; public class ProgrammerApp {/*** @param args*/public static void main(String[] args) {//1)、创建真实角色Programmer pro =new Programmer(); //2)、创建代理角色 +真实角色引用Thread proxy =new Thread(pro);//3)、调用 .start() 启动线程 proxy.start();for(int i=0;i<10;i++){System.out.println("一边聊qq...."+i);}}} /*一边聊qq....0 一边聊qq....1 一边聊qq....2 一边聊qq....3 一边聊qq....4 一边聊qq....5 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边敲helloworld.... 一边聊qq....6 一边聊qq....7 一边聊qq....8 一边聊qq....9*/
ProgrammerApp
package com.zwj.thread; /*** 方便共享资源* @author Administrator**/ public class Web12306 implements Runnable {private int num =10;@Overridepublic void run() {while(true){if(num<=0){break; //跳出循环 }System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}}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();} }/*路人甲抢到了10 路人甲抢到了8 路人甲抢到了7 路人甲抢到了6 路人甲抢到了5 路人甲抢到了4 路人甲抢到了3 路人甲抢到了2 路人甲抢到了1 黄牛已抢到了9 */
Web12306
三、了解
通过Callable接口实现多线程
优点:可以获取返回值
Callable 和 Future接口
Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
Callable和Runnable有几点不同:
(1)Callable规定的方法是call(),而Runnable规定的方法是run().
(2)call()方法可抛出异常,而run()方法是不能抛出异常的。
(3) Callable的任务执行后可返回值,运行Callable任务可拿到一个Future对象,而Runnable的任务是不能返回值的。
Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
缺点 :繁琐
思路:
1)、创建 Callable实现类+重写call
2)、借助 执行调度服务 ExecutorService,获取Future对象
ExecutorService ser=Executors.newFixedThreadPool(2);
Future result =ser.submit(实现类对象)
3)、获取值 result.get()
4 )、 停止服务 ser.shutdownNow();
package com.zwj.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /*** 使用Callable创建线程* @author Administrator**/ public class Call {public static void main(String[] args) throws InterruptedException, ExecutionException {//创建线程ExecutorService ser=Executors.newFixedThreadPool(2);Race tortoise = new Race("老不死",1000);Race rabbit = new Race("小兔子",500);//获取值Future<Integer> result1 =ser.submit(tortoise) ;Future<Integer> result2 =ser.submit(rabbit) ;Thread.sleep(2000); //2秒tortoise.setFlag(false); //停止线程体循环rabbit.setFlag(false);int num1 =result1.get();int num2 =result2.get();System.out.println("乌龟跑了-->"+num1+"步");System.out.println("小兔子跑了-->"+num2+"步");//停止服务 ser.shutdownNow();} }class Race implements Callable<Integer>{private String name ; //名称private long time; //延时时间private boolean flag =true;private int step =0; //步public Race() {} public Race(String name) {super();this.name = name;}public Race(String name,long time) {super();this.name = name;this.time =time;}@Overridepublic Integer call() throws Exception {while(flag){Thread.sleep(time); //延时step++;}return step;}public String getName() {return name;}public void setName(String name) {this.name = name;}public long getTime() {return time;}public void setTime(long time) {this.time = time;}public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public int getStep() {return step;}public void setStep(int step) {this.step = step;}} /*乌龟跑了-->3步 小兔子跑了-->5步 */
Call
(三)
1.新建状态(New):
当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码
2.就绪状态(Runnable)
一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。
处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。
3.运行状态(Running)
当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.
4. 阻塞状态(Blocked)
线程运行过程中,可能由于各种原因进入阻塞状态:
1>线程通过调用sleep方法进入睡眠状态;
2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
3>线程试图得到一个锁,而该锁正被其他线程持有;
4>线程在等待某个触发条件;
......
所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。
5. 死亡状态(Dead)
有两个原因会导致线程死亡:
1) run方法正常退出而自然死亡,
2) 一个未捕获的异常终止了run方法而使线程猝死。
为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是 可运行的, 或者线程死亡了,则返回false.
二、停止线程
1、自然终止:线程体正常执行完毕
2、外部干涉:
1)、线程类中 定义 线程体使用的标识
2)、线程体使用该标识
3)、提供对外的方法改变该标识
4)、外部根据条件调用该方法即可
package com.zwj.status; public class StopDemo01 {/*** @param args*/public static void main(String[] args) {Study s =new Study();new Thread(s).start();//外部干涉 当main线程执行50次时,study线程停止运行for(int i=0;i<100;i++){if(50==i){ //外部干涉 s.stop();}System.out.println("main.....-->"+i);}}} class Study implements Runnable{//1)、线程类中 定义 线程体使用的标识 private boolean flag =true;@Overridepublic void run() {//2)、线程体使用该标识while(flag){System.out.println("study thread....");}}//3)、对外提供方法改变标识public void stop(){this.flag =false;}}
StopDemo01
三、阻塞
1、join :合并线程, join()方法使调用该方法的线程在此之前执行完毕,也就是等待该方法的线程执行完毕后再往下继续执行。注意该方法也需要捕捉异常。
package com.zwj.status;/*** join:合并线程* @author Administrator**/ public class JoinDemo01 extends Thread {/*** @param args* @throws InterruptedException */public static void main(String[] args) throws InterruptedException {JoinDemo01 demo = new JoinDemo01();Thread t = new Thread(demo); //新生t.start();//就绪//cpu调度 运行for(int i=0;i<10;i++){if(5==i){t.join(); //执行JoinDemo01线程 main线程等待上一个线程执行完后在执行... }System.out.println("main...."+i);}}@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println("join...."+i);}}} /*main....0 join....0 main....1 join....1 main....2 join....2 main....3 main....4 join....3 join....4 join....5 join....6 join....7 join....8 join....9 main....5 main....6 main....7 main....8 main....9 */
JoinDemo01
2、yield:暂停自己的线程 static, 该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
package com.bjsxt.thread.status;public class YieldDemo01 extends Thread {/*** @param args*/public static void main(String[] args) {YieldDemo01 demo = new YieldDemo01();Thread t = new Thread(demo); //新生t.start();//就绪//cpu调度 运行for(int i=0;i<1000;i++){if(i%20==0){//暂停本线程 main Thread.yield();}System.out.println("main...."+i);}}@Overridepublic void run() {for(int i=0;i<1000;i++){System.out.println("yield...."+i);}}}
YieldDemo01
3、sleep:休眠,不释放锁
1)、与时间相关:倒计时
2)、模拟网络延时
3)、使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。
package com.zwj.status; import java.text.SimpleDateFormat; import java.util.Date;/*** 倒计时* 1、倒数10个数,一秒内打印一个* 2、倒计时* @author Administrator**/ public class SleepDemo01 {/*** @param args* @throws InterruptedException */public static void main(String[] args) throws InterruptedException {test1();Date endTime =new Date(System.currentTimeMillis()+10*1000);long end =endTime.getTime();while(true){//输出System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(endTime));//等待一秒Thread.sleep(1000);//构建下一秒时间endTime =new Date(endTime.getTime()-1000);//10秒以内 继续 否则 退出if(end-10000>endTime.getTime()){break;}}}/*倒计时 10 */public static void test1() throws InterruptedException{int num =10;while(true){System.out.println(num--);Thread.sleep(1000); //暂停 1000毫秒等于1秒if(num<=0){break;}}} /*10 9 8 7 6 5 4 3 2 1 2017-11-12 12:46:38 2017-11-12 12:46:37 2017-11-12 12:46:36 2017-11-12 12:46:35 2017-11-12 12:46:34 2017-11-12 12:46:33 2017-11-12 12:46:32 2017-11-12 12:46:31 2017-11-12 12:46:30 2017-11-12 12:46:29 2017-11-12 12:46:28*/ }
SleepDemo01
package com.zwj.status; /*** Sleep模拟 网络延时 线程不安全的类* @author Administrator**/ public class SleepDemo02 {/*** @param args*/public static void main(String[] args) {//真实角色Web12306 web= new Web12306();Web12306 web2 = 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 =10;@Overridepublic void run() {while(true){if(num<=0){break; //跳出循环 }try {//500毫秒Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}}} /*黄牛已抢到了10 路人甲抢到了9 攻城师抢到了8 路人甲抢到了7 黄牛已抢到了6 攻城师抢到了5 黄牛已抢到了4 路人甲抢到了3 攻城师抢到了2 黄牛已抢到了0 路人甲抢到了1 攻城师抢到了-1*/
SleepDemo02
(四)
同步:并发 多个线程访问同一份资源 确保资源安全 -->线程安全
synchronized -->同步
一、同步块
synchronized(引用类型|this|类.class){
}
二、同步方法
synchronized
三、死锁: 过多的同步容易造成死锁
package com.zwj.synchronizeds; public class SynDemo01 {/*** @param args*/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();}} /*** 线程安全的类* @author Administrator**/ class Web12306 implements Runnable {private int num =10;private boolean flag =true;@Overridepublic void run() {while(flag){//test5(); test4();//test3(); 线程安全 锁定正确 同步代码块//test2(); 线程安全 锁定正确 同步方法 static synchronized//test1(); 线程不安全 }}public void test6(){if(num<=0){flag=false; //跳出循环return ;}//a b c synchronized(this){try {Thread.sleep(500); //模拟 延时} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}}//线程不安全 锁定资源不正确public void test5(){//a b csynchronized((Integer)num){if(num<=0){flag=false; //跳出循环return ;}try {Thread.sleep(500); //模拟 延时} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}}//锁定范围不正确 线程不安全public void test4(){// c 1synchronized(this){//bif(num<=0){flag=false; //跳出循环return ;}}// btry {Thread.sleep(500); //模拟 延时} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}//a -->1//线程安全 锁定正确 同步代码块public void test3(){//a b csynchronized(this){if(num<=0){flag=false; //跳出循环return ;}try {Thread.sleep(500); //模拟 延时} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}}//线程安全 锁定正确 同步方法 static synchronizedpublic synchronized void test2(){if(num<=0){flag=false; //跳出循环return ;}try {Thread.sleep(500); //模拟 延时} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);}//线程不安全public void test1(){if(num<=0){flag=false; //跳出循环return ;}try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"抢到了"+num--);} }
SynDemo01
package com.zwj.synchronizeds; /*** 单例创建的方式* 1、懒汉式* 1)、构造器私有化* 2)、声明私有的静态属性* 3)、对外提供访问属性的静态方法,确保该对象存在* * @author Administrator**/ public class MyJvm {private static MyJvm instance;private MyJvm(){}public static MyJvm getInstance (){if(null==instance){ //提供效率synchronized(MyJvm.class){if(null==instance){ //安全instance =new MyJvm();}}}return instance;}} /*** 饿汉式1)、构造器私有化 * 2)、声明私有的静态属性,同时创建该对象* 3)、对外提供访问属性的静态方法* @author Administrator**/ class MyJvm2 {private static MyJvm2 instance =new MyJvm2();private MyJvm2(){}public static MyJvm2 getInstance (){ return instance;}} /*** 类在使用的时候加载 ,延缓加载时间* @author Administrator**/ class MyJvm3 {private static class JVMholder{private static MyJvm3 instance =new MyJvm3();}private MyJvm3(){}//不调用此方法就不会加载jvmholder静态内部类public static MyJvm3 getInstance (){ return JVMholder.instance;}}
MyJvm
package com.zwj.synchronizeds;/*** 单例设计模式:确保一个类只有一个对象* @author Administrator**/ public class SynDemo02 {/*** @param args*/public static void main(String[] args) {JvmThread thread1 = new JvmThread(100);JvmThread thread2 = new JvmThread(500);thread1.start();thread2.start();}} class JvmThread extends Thread{private long time;public JvmThread() {}public JvmThread(long time) {this.time =time;}@Overridepublic void run() { System.out.println(Thread.currentThread().getName()+"-->创建:"+Jvm.getInstance(time));} }/*** 单例设计模式* 确保一个类只有一个对象* 懒汉式 double checking* 1、构造器私有化,避免外部直接创建对象* 2、声明一个私有的静态变量* 3、创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象*/ class Jvm {//声明一个私有的静态变量private static Jvm instance =null; //构造器私有化,避免外部直接创建对象private Jvm(){}//创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象public static Jvm getInstance(long time){// c d e -->效率 提供 已经存在对象的访问效率if(null==instance){ // a bsynchronized(Jvm.class){if(null==instance ){try {Thread.sleep(time); //延时 ,放大错误} catch (InterruptedException e) {e.printStackTrace();}instance =new Jvm();}}}//areturn instance;}public static Jvm getInstance3(long time){//a b c d e -->效率不高 c 存在对象也需要等待synchronized(Jvm.class){if(null==instance ){try {Thread.sleep(time); //延时 ,放大错误} catch (InterruptedException e) {e.printStackTrace();}instance =new Jvm();}return instance;}}public static synchronized Jvm getInstance2(long time){if(null==instance ){try {Thread.sleep(time); //延时 ,放大错误} catch (InterruptedException e) {e.printStackTrace();}instance =new Jvm();}return instance;}public static Jvm getInstance1(long time){if(null==instance ){try {Thread.sleep(time); //延时 ,放大错误} catch (InterruptedException e) {e.printStackTrace();}instance =new Jvm();}return instance;} }
SynDemo02
package com.zwj.synchronizeds; /*** 过多的同步方法可能造成死锁* @author Administrator**/ public class SynDemo03 {/*** @param args*/public static void main(String[] args) {Object g =new Object();Object m = new Object();Test t1 =new Test(g,m);Test2 t2 = new Test2(g,m);Thread proxy = new Thread(t1);Thread proxy2 = new Thread(t2);proxy.start();proxy2.start();}} class Test implements Runnable{Object goods ;Object money ;public Test(Object goods, Object money) {super();this.goods = goods;this.money = money;}@Overridepublic void run() {while(true){test();}}public void test(){synchronized(goods){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}synchronized(money){}}System.out.println("一手给钱");}}class Test2 implements Runnable{Object goods ;Object money ;public Test2(Object goods, Object money) {super();this.goods = goods;this.money = money;}@Overridepublic void run() {while(true){test();}}public void test(){synchronized(money){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}synchronized(goods){}}System.out.println("一手给货");}}
SynDemo03
(五)
信号灯法
一、 wait() :等待,释放锁 sleep 不释放锁
二、notify()/notifyAll():唤醒
与 synchronized 一起使用
package com.zwj.pro; /**一个场景,共同的资源生产者消费者模式 信号灯法wait() :等待,释放锁 sleep 不释放锁notify()/notifyAll():唤醒与 synchronized* @author Administrator**/ public class Movie {private String pic ;//信号灯//flag -->T 生产生产,消费者等待 ,生产完成后通知消费//flag -->F 消费者消费 生产者等待, 消费完成后通知生产private boolean flag =true;/*** 播放* @param pic*/public synchronized void play(String pic){if(!flag){ //生产者等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//开始生产try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("生产了:"+pic);//生产完毕 this.pic =pic;//通知消费this.notify();//生产者停下this.flag =false;}public synchronized void watch(){if(flag){ //消费者等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//开始消费try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("消费了"+pic);//消费完毕//通知生产this.notifyAll();//消费停止this.flag=true;} }
Movie
package com.zwj.pro; /*** 生产者* @author Administrator**/ public class Player implements Runnable {private Movie m ;public Player(Movie m) {super();this.m = m;}@Overridepublic void run() {for(int i=0;i<20;i++){if(0==i%2){m.play("左青龙"+i);}else{m.play("右白虎"+i);}}}}
Player
package com.zwj.pro; public class Watcher implements Runnable {private Movie m ;public Watcher(Movie m) {super();this.m = m;}@Overridepublic void run() {for(int i=0;i<20;i++){m.watch();}}}
Watcher
package com.zwj.pro;public class App {public static void main(String[] args) {//共同的资源Movie m = new Movie();//多线程Player p = new Player(m);Watcher w = new Watcher(m);new Thread(p).start(); new Thread(w).start();} } /*生产了:左青龙0 消费了左青龙0 生产了:右白虎1 消费了右白虎1 生产了:左青龙2 消费了左青龙2 生产了:右白虎3 消费了右白虎3 生产了:左青龙4 消费了左青龙4 生产了:右白虎5 消费了右白虎5 生产了:左青龙6 消费了左青龙6 生产了:右白虎7*/
App
package com.zwj.pro;public class TestProduce {public static void main(String[] args) {SyncStack sStack = new SyncStack();Shengchan sc = new Shengchan(sStack);Xiaofei xf = new Xiaofei(sStack);sc.start();xf.start();} }class Mantou {int id;Mantou(int id){this.id=id;} }class SyncStack{int index=0;Mantou[] ms = new Mantou[10];public synchronized void push(Mantou m){while(index==ms.length){try {this.wait(); //wait后,线程会将持有的锁释放。sleep是即使睡着也持有互斥锁。} catch (InterruptedException e) {e.printStackTrace();}}this.notify(); //唤醒在当前对象等待池中等待的第一个线程。notifyAll叫醒所有在当前对象等待池中等待的所有线程。//如果不唤醒的话。以后这两个线程都会进入等待线程,没有人唤醒。ms[index]=m;index++;}public synchronized Mantou pop(){while(index==0){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}this.notify();index--;return ms[index];} }class Shengchan extends Thread{SyncStack ss = null;public Shengchan(SyncStack ss) {this.ss=ss;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {System.out.println("造馒头:"+i);Mantou m = new Mantou(i);ss.push(m);}} }class Xiaofei extends Thread{SyncStack ss = null;public Xiaofei(SyncStack ss) {this.ss=ss;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {Mantou m = ss.pop();System.out.println("吃馒头:"+i);}} }
TestProduce
(六)
了解
Timer()
schedule(TimerTask task, Date time)
schedule(TimerTask task, Date firstTime, long period)
自学 juc quartz
package com.zwj.pro; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /**了解Timer() schedule(TimerTask task, Date time) schedule(TimerTask task, Date firstTime, long period) 自学 quartz* @author Administrator**/ public class TimeDemo01 {/*** @param args*/public static void main(String[] args) {Timer timer =new Timer();//从new Date(System.currentTimeMillis()+1000)开始执行200次timer.schedule(new TimerTask(){@Overridepublic void run() {System.out.println("so easy....");}}, new Date(System.currentTimeMillis()+1000), 200);}}
TimeDemo01
转载于:https://www.cnblogs.com/ou-pc/p/7821116.html
java基础---线程相关推荐
- java基础----线程
一.进程与线程 进程(process)是一个可并发执行的具有独立功能的程序(program)关于某个数据集合的一次执行过程,也是操作系统进行资源分配和保护的基本单位. 线程(thread)是操作系统进 ...
- Java基础——线程及并发机制
前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...
- Java 基础 —— 线程安全
一.线程安全问题 线程安全 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的 ...
- java基础线程_Java基础之多线程没那么复杂!
多线程的引入 1.什么是多线程 线程是程序执行的一条路径,一个进程中可以包含多条线程;多线程并发执行可以提高程序的效率 2.进程和线程之间的关系 操作系统可以同时执行多个任务,每个任务就是进程;进程可 ...
- [Java基础]线程安全的类
package ThreadDemoPack01;import java.util.*;public class ThreadDemo01 {public static void main(Strin ...
- Java基础 线程同步
线程的同步:在编程过程中,为了防止多线程访问共享资源时发生冲突,Java提供了线程同步机制.所谓同步,就是指一个线程等待另一个线程操作完再继续的情况. 线程安全:一个类很好地同步以保护它的数据,这个类 ...
- java基础—线程间的通讯 生产者与消费者
线程间的的通讯 生产者与消费者 public class TestDemos3 {public static void main(String[] args){Res r = new Res();I ...
- java基础 - 线程
5.线程 进程:是正在运行的程序. 是系统进行资源分配和调用的独立单位. 每一个进程都有它自己的内存空间和系统资源. 线程:是进程中的单个顺序控制流,是一条执行路径. 单线程:一个进程如果只有一条执行 ...
- Java基础——线程基础
线程相关概念 程序 程序就是为完成特定任务.用某种语言编写的一组指令的集合.简单来说就是我们写的代码. 进程 进程是指运行中的程序,比如我们打开一个应用,就是启动了一个进程,操作系统就会为该进程分配内 ...
- [Java基础]线程同步之卖票案列分析
案列: 卖票. 需求: 某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票. 代码如下: package SellTicketPack;public cl ...
最新文章
- android自定义折线图可左右滑动,25.Android自定义折线图,可左右滑动
- 实现EditText输入金额(小数点后两位)
- FPGA之道(45)正确的变量访问思路
- Linux dmesg 命令学习
- 听说你想去大厂看学妹,带你看看京东软件产品经理面经
- aspects to consider for a recommendation letter
- 基于云平台的家居综合监测管理系统的设计与实现
- Nginx大规模并发原理
- 怎么查看电脑有没有python_使用python获取电脑的磁盘信息方法
- Python:print用法大全
- c语言easyx输出文字_做游戏,学编程(C语言) 6 数组之空战游戏
- vue用户行为收集_Vue前端数据采集 埋点 追踪用户系列行为
- ADSL密码查看器绿色版
- 利用APPInventor开发手机APP,实现OBLOQ-IOT与Arduino设备通信
- 一网打尽系列之史玉柱运营法则
- opencv毛孔识别(python实现)
- 奇迹服务器gs无响应,奇迹服务端1.03K比较有特色的拓展GS
- 中国软件,从繁荣走向文明
- 20171218Capstone培训班
- 基于Java的学生在线选课系统设计与实现
热门文章
- 牛津大学数学与计算机科学课程,牛津大学之数学专业
- fuzzy仿真 MATLAB,基于Matlab的Fuzzy-PID控制器的设计与仿真
- UserWarning: Error checking compiler version for cl
- R-FCN算法及Caffe代码详解
- 【论文笔记】Learning Deep Face Representation
- linux软链接删除重新创显示,Linux 下如何创建 /删除软连接
- mysql Sql slow log_mysql 5.5 开启慢日志slow log的方法(log_slow_queries)
- kubernetes视频教程笔记 (25)-集群调度-调度过程说明
- Kubernetes 小白学习笔记(8)--kubernetes的基础概念
- Docker教程小白实操入门(8)--基于save保存镜像与基于load加载镜像