- 创建线程三种方法:
/**
* 线程创建方法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;
}
}