(一)  

一、程序 进程 线程
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基础---线程相关推荐

  1. java基础----线程

    一.进程与线程 进程(process)是一个可并发执行的具有独立功能的程序(program)关于某个数据集合的一次执行过程,也是操作系统进行资源分配和保护的基本单位. 线程(thread)是操作系统进 ...

  2. Java基础——线程及并发机制

    前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...

  3. Java 基础 —— 线程安全

    一.线程安全问题 线程安全 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的 ...

  4. java基础线程_Java基础之多线程没那么复杂!

    多线程的引入 1.什么是多线程 线程是程序执行的一条路径,一个进程中可以包含多条线程;多线程并发执行可以提高程序的效率 2.进程和线程之间的关系 操作系统可以同时执行多个任务,每个任务就是进程;进程可 ...

  5. [Java基础]线程安全的类

    package ThreadDemoPack01;import java.util.*;public class ThreadDemo01 {public static void main(Strin ...

  6. Java基础 线程同步

    线程的同步:在编程过程中,为了防止多线程访问共享资源时发生冲突,Java提供了线程同步机制.所谓同步,就是指一个线程等待另一个线程操作完再继续的情况. 线程安全:一个类很好地同步以保护它的数据,这个类 ...

  7. java基础—线程间的通讯 生产者与消费者

    线程间的的通讯  生产者与消费者 public class TestDemos3 {public static void main(String[] args){Res r = new Res();I ...

  8. java基础 - 线程

    5.线程 进程:是正在运行的程序. 是系统进行资源分配和调用的独立单位. 每一个进程都有它自己的内存空间和系统资源. 线程:是进程中的单个顺序控制流,是一条执行路径. 单线程:一个进程如果只有一条执行 ...

  9. Java基础——线程基础

    线程相关概念 程序 程序就是为完成特定任务.用某种语言编写的一组指令的集合.简单来说就是我们写的代码. 进程 进程是指运行中的程序,比如我们打开一个应用,就是启动了一个进程,操作系统就会为该进程分配内 ...

  10. [Java基础]线程同步之卖票案列分析

    案列: 卖票. 需求: 某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票. 代码如下: package SellTicketPack;public cl ...

最新文章

  1. android自定义折线图可左右滑动,25.Android自定义折线图,可左右滑动
  2. 实现EditText输入金额(小数点后两位)
  3. FPGA之道(45)正确的变量访问思路
  4. Linux dmesg 命令学习
  5. 听说你想去大厂看学妹,带你看看京东软件产品经理面经
  6. aspects to consider for a recommendation letter
  7. 基于云平台的家居综合监测管理系统的设计与实现
  8. Nginx大规模并发原理
  9. 怎么查看电脑有没有python_使用python获取电脑的磁盘信息方法
  10. Python:print用法大全
  11. c语言easyx输出文字_做游戏,学编程(C语言) 6 数组之空战游戏
  12. vue用户行为收集_Vue前端数据采集 埋点 追踪用户系列行为
  13. ADSL密码查看器绿色版
  14. 利用APPInventor开发手机APP,实现OBLOQ-IOT与Arduino设备通信
  15. 一网打尽系列之史玉柱运营法则
  16. opencv毛孔识别(python实现)
  17. 奇迹服务器gs无响应,奇迹服务端1.03K比较有特色的拓展GS
  18. 中国软件,从繁荣走向文明
  19. 20171218Capstone培训班
  20. 基于Java的学生在线选课系统设计与实现

热门文章

  1. 牛津大学数学与计算机科学课程,牛津大学之数学专业
  2. fuzzy仿真 MATLAB,基于Matlab的Fuzzy-PID控制器的设计与仿真
  3. UserWarning: Error checking compiler version for cl
  4. R-FCN算法及Caffe代码详解
  5. 【论文笔记】Learning Deep Face Representation
  6. linux软链接删除重新创显示,Linux 下如何创建 /删除软连接
  7. mysql Sql slow log_mysql 5.5 开启慢日志slow log的方法(log_slow_queries)
  8. kubernetes视频教程笔记 (25)-集群调度-调度过程说明
  9. Kubernetes 小白学习笔记(8)--kubernetes的基础概念
  10. Docker教程小白实操入门(8)--基于save保存镜像与基于load加载镜像