ITPub博客

首页 > 应用开发 > Java > JAVA中线程的创建

JAVA中线程的创建

原创 Java 作者:蝴蝶飞啊飞 时间:2019-11-06 14:10:03 0 删除 编辑

一、线程(Thread)

1. 线程

线程:是指程序中的顺序流

多线程:一个程序中的多个顺序流同时执行

(1) 线程的状态:

新生

就绪

运行

阻塞

终止

(2) 学习多线程:

1) 线程的创建

2) 线程的状态

3) 线程的安全

4) 线程的通信

2. 线程的创建

1) 继承 Thread ,重写 run() 方法

(1) run() 方法中定义线程体

(2) 开启:使用 start() 方法开启线程

// 继承 Tread

public class Thread01 extends Thread{

// 重写 run() 方法

// 多线程的线程体

@Override

public void run() {

for(int i=1;i<=20;i++){

System.out.println(" 一边敲代码 ...");

}

}

public static void main(String[] args) {

// 开启多线程 创建线程

Thread01 th=new Thread01();

// 开启线程

th.start();

//th.run();    注意 : 这是方法的调用 , 不是多线程的开启

for(int i=1;i<=20;i++){

System.out.println(" 一边聊天 ...");

}

}

}

2) 实现 Runnable 接口,重写 run() 方法(推荐使用,线程安全)

开启:通过外汇返佣http://www.kaifx.cn/Tread 类中的 start() 方法开启线程

优点: (1) 避免了单继承的局限性

(2) 实现资源的共享

public class Thread02 implements Runnable{

// 定义线程体的方法 , 当被调用的时候 , 会逐行执行里面的代码

@Override

public void run() {

for(int i=1;i<=100;i++){

System.out.println(" 一边敲代码 ...");

}

}

public static void main(String[] args) {

Thread02 th=new Thread02();

// 开启线程 // 创建线程

Thread t=new Thread(th);  // 因为开启线程的方法在 Thread 类中 ,Thread 做为代理类出现

t.start();

for(int i=1;i<=100;i++){

System.out.println(" 一边聊天 ...");

}

}

}

实现资源共享:

/*

 * 模拟铁路 12306

 * 需求: 100 张票 ,3 个人买完

 * 资源共享: 100 张票

 */

public class Thread03 implements Runnable{

// 成员 资源

int tikets=100;

@Override

public synchronized void run() {

// 循环买票

while(true){

if(tikets<=0){

break;

}

// 捕捉异常

//static void   sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响

try {

Thread.sleep(100);  // 线程睡眠 100ms

} catch (InterruptedException e) {

e.printStackTrace();

}

//static Thread    currentThread() 返回对当前正在执行的线程对象的引用

//String     getName() 返回该线程的名称

System.out.println(Thread.currentThread().getName()+" 正在购买第 "+tikets--);

}

}

public static void main(String[] args) {

Thread03 th=new Thread03 ();

// 开启三个线程

Thread th1=new Thread(th," 张三 ");

Thread th2=new Thread(th," 李四 ");

Thread th3=new Thread(th," 王五 ");

th1.start();

th2.start();

th3.start();

}

}

3) 实现 Callable 接口,重写 call() 方法,方法中定义线程体(了解)

优点:可以抛出异常,可以有返回值

// 导包

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 接口   <> 可以添加泛型,引用类型的数据

public class Race05 implements Callable<Integer>{

// 存储赢的人的名字

String winner=null;

// 重写 call() 方法,方法中定义线程体

@Override

public Integer call() throws Exception {

// 开始游戏 , 循环停止游戏结束

for(int i=1;i<=100;i++){

if(" 兔子 ".equals(Thread.currentThread().getName()) && i%10==0){

try {

Thread.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+" 正在跑第 "+i+" ");

// 调用有 Boolean 类型返回值的结束方法

boolean flag=over(i);

// 判断返回值是 true ,或为 false

if(flag){

return i;

}

}

return -1;

}

/**

 * @param steps   当前线程的步数

 * 返回值 : 如果有人赢了返回 true, 否则返回 false

 */

public boolean over(int steps){

if(winner!=null){

return true;

}else{

if(steps==100){

winner=Thread.currentThread().getName();

return true;

}

return false;

}

}

public static void main(String[] args) throws InterruptedException, ExecutionException {

Race05 race=new Race05();

//1. 创建执行服务

ExecutorService server=Executors.newFixedThreadPool(2);

//2. 提交执行

Future result1=server.submit(race);

Future result2=server.submit(race);

//3. 获取结果

Integer i1=(Integer) result1.get();

Integer i2=(Integer) result2.get();

System.out.println(i1+"---->"+i2);

//4. 关闭服务

server.shutdown();

}

}

2. 线程状态问题

1) 状态:

新生状态: new

就绪状态: start() 线程就会进入到就绪状态 , 线程会进入到就绪队列 , 等待 CPU 的调度

运行状态:

阻塞状态: 非常执行完毕 , 通过程序进行控制

终止状态:

注意: 一个线程一旦进入到终止状态 , 没有办法恢复了 , 就算是重写 new 一个线程 , 也不刚那个线程了,一个线程一旦进入到阻塞状态 , 无法直接恢复到运行 , 等待阻塞接触之后恢复到就绪状态

2) 如何进入到就绪状态

1 start()

2 )阻塞解除

3 )线程切换,被切换的线程进入到就绪状态

4 yield() 礼让线程

3) 如何进入到阻塞状态

1 sleep() 方法

2 join()

3 wait()

4) 如何让一个线程进入到终止状态

1 )正常执行完毕

2 destroy() |stop() 已过时

3 )通过标识手动判断

3.Thread 类的方法学习

1 sleep() 线程休眠

1. 模拟网络延迟

2. 放大问题的可能性

注意:sleep() 线程的休眠是抱着资源不放进行休眠,同步的是对象资源,让出的是 CPU 的资源

// 实现 Runnable 接口

public class State01 implements Runnable{

public static void main(String[] args) {

 new Thread(new State01()).start();

}

/*

 * 倒计时   10 9 8 7 6 5 4 3 2 1

 * 重写 run() 方法

 */

@Override

public void run() {

for(int i=10;i>=0;i--){

// 模拟网络延迟

try {

Thread.sleep(1000);   //sleep() 线程的休眠 1000ms=1s

} catch (InterruptedException e) {

e.printStackTrace();

}

if(i==0){

System.out.println(" 过年好 ...");

break;

}

System.out.println(i);

}

}

}

2 yield() 礼让线程

static Thread   currentThread()  

返回对当前正在执行的线程对象的引用

String   getName()  

返回该线程的名称

//static void     yield() 暂停当前正在执行的线程对象,并执行其他线程

public class Yield03 implements Runnable{

public static void main(String[] args) {

new Thread(new Yield03(),"A").start();

new Thread(new Yield03(),"B").start();

}

@Override

public void run() {

System.out.println(Thread.currentThread().getName()+"start...");

//yield() 礼让线程,等待 CPU 的再度调用,但是是随机分配

Thread.yield();  // 静态方法

System.out.println(Thread.currentThread().getName()+"end...");

}

}

3 getState() 方法

Thread.State  getState()

  返回该线程的状态

void  setPriority(int newPriority)

更改线程的优先级

/*

 * getState() 方法

 * 线程的优先级: 提高优先执行的可能性 , 但是不一定就会先执行

 * void setPriority(int newPriority) 更改线程的优先级。

 * 优先级分为1~10 1 最小   10 最大

 * Thread.NORM_PRIORITY 5 ( 默认为 5)

 * Thread.MAX_PRIORITY  10

 * Thread.MIN_PRIORITY  1

 */

public class GetState04 {

public static void main(String[] args) {

Thread th=new Thread(()->{

for(int i=1;i<=10;i++){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(" 一边学习 ...");

}

});

th.setPriority(Thread.NORM_PRIORITY);

System.out.println(th.getPriority());

System.out.println(th.getState());//NEW

th.start();

System.out.println(th.getState());//RUNNABLE

for(int i=1;i<=10;i++){

if(i==5){

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(th.getState());

}

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(th.getState());

if(th.getState()== Thread.State.TERMINATED){

System.out.println(" 终止 ");

}

}

}

4 join() 合并线程,插队线程

void join()

       等待该线程终止。

 void join(long millis)

       等待该线程终止的时间最长为 millis 毫秒。

void join(long millis, int nanos)

       等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒

/*

 * join() 合并线程 , 插队线程

模拟:父亲让儿子去买烟的过程

 */

public class JoinDemo05 {

public static void main(String[] args) {

new Thread(new Father()).start();

}

}

class Father implements Runnable{

@Override

public void run() {

System.out.println(" 想抽烟 ...");

System.out.println(" 给儿子钱,让儿子去买烟 ..");

Thread th=new Thread(new Son());

th.start();

try {

th.join();// 合并线程

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println(" 儿子丢了 , 赶紧去找儿子 ..");

}

System.out.println(" 接过烟 , 吸一口 , ~");

}

}

class Son  implements Runnable{

@Override

public void run() {

System.out.println(" 接过前 , 给老爸去买烟 ...");

System.out.println(" 路边有个电玩城 , 进去玩 10s...");

for(int i=1;i<=10;i++){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(i+"s...");

}

System.out.println(" 赶紧去买烟 ...");

System.out.println(" 把烟给老爸 , 前揣兜里 ...");

}

}

4. 线程安全

多个线程同时操作同一个资源的时候, 才可能会出现线程安全问题

1 synchronized 关键字

通过同步synchronized 关键字控制线程安全 :

同步方法

静态方法

成员方法

同步块 synchronized ( |this| 资源 ){ 代码 }

: 类名 .class 一个类的 Class 对象 一个类只有一个 Class 对象

// 通过同步 synchronized 关键字控制线程安全

public class Single01 {

public void main(String[] args) {

new Thread(()->{System.out.println(Single.newInstance());}).start();;

new Thread(()->{System.out.println(Single.newInstance());}).start();;

}

}

class Single{

//2. 私有的静态的该类的引用

private static Single single=null;

//1. 构造器私有话

private Single(){}

//3. 公共的静态的方法

// 在方法上添加锁 , 锁方法

/*public static synchronized Single newInstance(){

if(single==null){

single=new Single();

}

return single;

}*/

// 同步块

/*public static Single newInstance(){

synchronized (Single.class) {  // 控制多线程排队执行

if(single==null){

single=new Single();

}

}  //{} 中的代码就是排队执行的代码

return single;

}*/

public static Single newInstance(){

if(single==null){

//A B C

synchronized (Single.class) {  // 控制多线程排队执行

// 双重检查 double check

if(single==null){

single=new Single();

}

}  //{} 中的代码就是排队执行的代码

}

return single;

}

}


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69946279/viewspace-2662888/,如需转载,请注明出处,否则将追究法律责任。

上一篇: Mustache要点总结
下一篇: java框架之mybatis
请登录后发表评论 登录
全部评论
管他谁是谁非,做自己的主宰,我是这条街最亮的崽!

注册时间:2019-08-22

  • 博文量
    49
  • 访问量
    21288