多线程之创建线程方式和注意事项

目录

创建线程方式一:

创建线程方式二:

线程安全:

解决线程安全方式3:通过增加锁lock来实现线程安全;

面试题:

面试题:

创建多线程方式三:实现Callable()接口:

创建线程方式4:使用线程池


创建线程方式一:

1:新建子类继承Thread类

2:重写run()方法-->把该线程需要执行的代码放入run()方法中

3;创建子类对象,执行对象.start()方法

代理对象线程:new Thread(){

                                run();   //重写run方法

                        }.start()

----------------------------------------------------------------------------------------------------------

thread中常用的方法:

1:start();        启动线程,调用当前线程的run方法

2:run();        重写Thread类中的此方法,把该线程才需要执行的操作声明放入其中

3 : currentThread();        静态方法,返回执行当前代码的线程

4 : yirld();        释放CPU当前的执行权

5 : join();        在线程a中加入线程b的join(),a进入阻塞状态,只有当b执行完才会结束a线程的阻塞 状态

6 : sleep(long millitime);        静态方法,让线程睡眠指定毫秒数

7:getname();        获取挡墙线程的名字

8:setname();        设置当前线程的名字

9:isAlive();        判断当前线程是否存活

------------------------------------------------------------------------------------------------------------------

线程优先级:MAX_PRIORITY:10

                      NOR_PRIORITY:5

                      MIN_PRIORITY:1

getPriority();       得到当前线程的优先级

setPriority(int  i);        设置当前线程的优先级

说明:高优先级的线程强占低优先级的CPU执行权,但是只是概率的有更高的优先权,并不意味着只有当执行完高优先级的才执行低优先级的线程,这只是概率问题;

****************************************************************************************************

创建线程方式二:

1.新建子类继承接口Runnable,重写run()方法;

2.创建实现类的对象;

3.把此对象作为参数传递到Thread类的构造器中,创建Thread类的对象;

4.通过Thread类的对象调用start()方法;

 *******************************************************************************************************

线程安全

同步代码块:synchronized(同步监视器){

                                        //需要被同步的代码;

                                        }

1.需要被共享的数据,即为需要被同步的代码;多个线程操作的变量即为共享数据;

2.同步监视器,俗称锁,任何一个类的对象都可以充当锁,多个线程必须共用同一把锁

补充:在使用Runnable接口创建多线程方式中,可以使用this充当同步监视器;

同步方法:如果操作共享数据的代码在同一个方法中,可以设这个方法为同步方法;

1.非静态的同步方法,同步监视器是this,即当前线程类的对象;

2.静态同步方法,同步监视器是当前类本身;

不足:操作同步代码时,只有一个线程运行,其他线程必须等待,相当于单线程,效率较低;

解决线程安全方式3:通过增加锁lock来实现线程安全;

private ReetrantLock lock = new ReentrantLock();

方法:

        lock.lock();          //调用锁定方法

        lock.unlock();        //调用解锁方法

补充:如果使用接口Runnable使用上述方法即可;

           如果继承Thread则需要把上述方法该为静态即可;

面试题:

synchronized与lock()的区别:

1.Lock是手动锁(需要手动开启和关闭锁,别忘了关闭锁),synchronized是自动锁,出了作用域自动释放

2.Lock只有锁代码块,synchronized有代码块锁和方法锁;

3.Lock锁JVM将花费更少的时间来调度线程,性能更好,并且有更好的扩展性;

线程通信的3种方法:

1.wait();一旦使用这个方法,线程进入阻塞状态,同时释放同步监视器;

2.notify();执行此方法,将唤醒被wait的一个线程,如果有多个线程,将唤醒优先级高的那个线程;

3.notifyAll();执行此方法,将唤醒所有被wait的线程;

补充:这3个方法必须在同步代码块或同步方法中;3个方法的调用者必须是同步监视器;

面试题:

sleep和wait的异同:

同:使用时都会使当前线程进入阻塞;

异:1)sleep()声明在Thread类中,wait()声明在Object类中;

2)wait()只能声明在同步方法或同步代码块中,而sleep()能声明在任何地方;

3)如果2个方法都使用在同步方法或同步代码块中,sleep()不会释放锁,而wait ()会释放锁;

***********************************************************************************************************

创建多线程方式三:实现Callable()接口:

与Runnable的比较:1)相比run()方法,可以有返回值

                                   2)方法可以抛出异常

                                   3)支持泛型的返回值

                                   4)需要借助FutureTask类,比如获取返回结果

Future接口:

1)可以对Runnable,Callable等任务的进行取消,查询结果是否完成,获取结果等;

2)FutureTask是Future接口的唯一实现类;

3)FutureTask同时实现了Runnable,Future接口,因此既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值;

步骤:1)创建实现Callable接口的实现类,重写call()方法;将此线程需要执行的操作声明在call()方法中;

2)创建Callable接口的实现类的对象;

3)将创建Callable接口的实现类的对象作为参数传递到FutureTask的构造器当中,创建FutureTask对象;

4)将FutureTask对象作为参数传递到Thread构造器当中,创建Thread对象,并执行start()方法;

5)可选:获取Callable接口中call方法的返回值,调用FutureTask对象的get()方法得到返回值,返回值可以赋值给变量;

**************************************************************************************************************

创建线程方式4:使用线程池

好处:1)提高响应速度;(减少了创建线程的时间)

2)便于线程管理;

3)降低资源消耗;(重复利用线程池中的线程,不需要每次都创建)

方法:1)corePoolSize:线程池的大小;

2)maxmumPoolSize:最大线程数;

3)keepAliveTime:线程没有任务是最多保存多长时间才会终止;

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注意事项: 1、主进程传入的对象或变量不管是不是ref线程内操作传入的引用都会影响主进程的对象或变量,且对象只能是nonvisualobject类型的。 2、基础变量如long等等都不能传引用ref会运行会报错 3、SharedObjectUnregister只是把SharedObjectDirectory中的去掉,实际内存不会释放必须destroy 4、主进程不能直接访问线程中的变量和对象,可以通过处理类私有的办法处理。 5、千万注意释放线程的时候一定要把线程里面的资源释放完,不然百分百卡死。比如一个线程里面有一个timing的计时器,如果不先stop(),直接destroy,百分百卡死。如果连接数据库或者其他接口时千万注意了!!!千万要在uf_stop()(此例子中的释放预留方法)里面把所有的资源都释放干净,资源都释放干净,源都释放干净,都释放干净,释放干净,放干净,干净,净…… 大体设计思路: 1、在主进程中建立一个“任务信息类”数组,其中包含“任务线程类”,一个任务对应一个线程。 2、在主进程中建立一个“任务管理类”,负责处理任务信息类。 简单举例: 1、新建1个“任务管理类”,再新建N“任务信息类”,将“任务信息类”赋值完成加入“任务管理类”,并创建一个“任务线程类”,此时线程开始running。 2、“任务线程类”中有一个内部timing类,监控自己是否执行完成,会改标志。“任务管理类”也有一个timing监控“任务信息类”和“任务线程类”的情况,把完成的结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值