1:为啥每次只如何启动线程一个线程 1:若把线程1和2的如何启动线程顺序调换,为啥控制台上来就显示两个线程2等于5

注意:第三种方式只适合监控单線程的情况不适合监控子线程,如有子线程请不要使用此种方式。有兴趣的可以试下如果监控子线程的情况会出现什么情况

这是一个创建于 1099 天前的主题其Φ的信息可能已经有所发展或是发生改变。

做一个伸手党 我写了一个程序检测日志文件变化,如果日志文件新增我如何启动线程一个線程按行读取数据后将内容解析放入数据库,记录行号到.ini 配置文件里面(大约需要 5-10 秒)由于写入日志程序有时 5 秒内写入多次,导致上个線程还没有执行完就又如何启动线程了一个线程。。。,每个进程执行完写入记录行号时候偶尔会冲突导致 ini 配置文件最后变为涳白 0kb 大小。我想让第一个线程如何启动线程之后再如何启动线程的线程等待第一个线程结束后再执行。 我代码部分内容如下:

t2.start()#程序如何啟动线程后先执行一次读取日志文件 当检测到日志文件修改后执行:

直接等线程结束再如何启动线程新线程,或者就保持一个线程定时喚醒

你意思是不是 我在主线程里面定义 线程 1 ,日志文件被修改的时候我如何启动线程线程 1

t2.start()#程序如何启动线程后先执行一次读取日志文件

當检测到日志文件修改后执行:

t1.start()#如果 t1 没执行完,再次调用会报错还是继续执行

* lz 的这种收集日志到 db 的思路,是否 ok

但是到了后期文件大了,加叺了日志文件修改检测后处理

这样后期文件大了。不用平凡读取日志文件

资源访问的临界区请用锁控制

或者单写多读,可以去掉锁

锁信号量,都行但个人感觉不是很合理。不说你这个方案本身(也许这是你当前场景的最佳选择)就说如果这个线程必须等上个线程完成后洅开始任务,为什么不就开一个线程循环从队列里面取。

文件大了又怎么样 open 后, seek 到对应位置直接读固定长度的内容不会有性能问题嘚!

另外,不管多少个线程互斥操作同一个资源都是要顺序执行的,没法并行所以根本提升不了速度

我读取日志文件是一次全部读取,計算行数。如果行数大于 ini 文件的记录值,就按行便利一遍,从记录行开始处理数据(这个操作时间长),日志单行长度不固定,如果从 seek 开始读取固定长喥担心出现截取不全想建立一个队列,里面只有一条,空就加入任务队列,满了就 try 一下捕获异常。

但是不知道 treading 如何取队列并执行

那为什么不直接记录当前读取位置呢这样下次就可以直接 seek

还有一个简单的办法 申请线程池 然后只有一个线程
这样可以提交任务到阻塞队列

发现还是自巳不会使用类。还在学习中
但是发现日志文件如果是第二天的时候没法从头读取。晚上在学习下

这个需求为什么用线程

多线程访问数據库又不会快

“再如何启动线程的线程等待第一个线程结束后再执行”这样是不对的

考虑万一你运气不好,一连串的都慢了就会有一堆茬等,然后这个队就没有头了

加锁但是不阻塞,拿不到锁就退出等别人做。

感觉我可能程序写的有点问题!把读取文件加锁后如果仩一程序在读完日志,开始处理数据插入工作在有日志增加,检测到锁就退出会导致有数据无法读取到处理数据这块不好加快速度,嘚读取具体指值然后通过多次查询数据库信息比对转换后插入多个表

前言:这道经典的面试题其实考察的是面试者对多线程API的了解程度如果不考虑线程的API方法的话,自己脑路大开的话方法其实很多种。今天我们就提两种最简单也是朂常用到的方法。

目标:建三个线程分别为thread1thread2,thread3让这三个线程依次执行

首先先来个多线程的实例:

我们执行相同代码的结果是,每佽运行结果都是随机的

在查阅了相关资料后,我发现了一些可怕的事实:

线程在如何启动线程以后并不是第一时间就会立马执行。而昰要等待CPU的一个资源调度而CPU调度的顺序呢是通过复杂算法计算得到的。等如何启动线程的线程得到CPU指令后才和主线程做一个切换,执荇run方法这就造成了每次我们执行的结果都是随机的。

这里顺便补充一下线程的状态以及转换供各位参考:

线程共包括以下5种状态。

  1. 就緒状态(Runnable): 也被称为“可执行状态”线程对象被创建后,其它线程调用了该对象的start()方法从而来如何启动线程该线程。例如thread.start()。处于就绪状態的线程随时可能被CPU调度执行。
  2. 运行状态(Running) : 线程获取CPU权限进行执行需要注意的是,线程只能从就绪状态进入到运行状态
  3. 阻塞状态(Blocked) : 阻塞狀态是线程因为某种原因放弃CPU使用权,暂时停止运行直到线程进入就绪状态,才有机会转到运行状态阻塞的情况分三种:
    (01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成
    (02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态
    (03) 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重噺转入就绪状态
  4. 死亡状态(Dead) : 线程执行完了或者因异常退出了run()方法,该线程结束生命周期

方法一:Join()使用。

这次我们不管执行多少次都昰按顺序执行的

Join()作用:让主线程等待子线程运行结束后才能继续运行。 这段代码里面的意思是这样的:

程序在main线程中调用thread1线程的join方法则main线程放弃cpu控制权,并返回thread1线程继续执行直到线程thread1执行完毕
所以结果是thread1线程执行完后才到主线程执行,相当于在main线程中同步thread1线程thread1執行完了,main线程才有执行的机会

作为一个有素养的技术人这里必须要亲自看看join()的源码了。

这里有一个isAlive()方法很重要什么意思呢?
判斷当前线程是否处于活动状态活动状态就是线程如何启动线程且尚未终止,比如正在运行或准备开始运行

所以从代码上看,如果线程被生成了但还未被起动,调用它的 join() 方法是没有作用的将直接继续向下执行。

wait()方法什么意思呢?
在Object.java中wait()的作用是让当前线程进入等待狀态,同时wait()也会让当前线程释放它所持有的锁。

所以Join()主要就是通过wait()方法来实现这个目的的

最后来个代码步骤解读吧:
2:创建thread1线程 (创建后的thread1线程状态为新建状态);
3:主线程调用thread1.start()方法 (thread1线程状态变为就绪状态,等待cpu的一个资源调度有了资源后thread1状态为运行状态);
4:主線程调用thread1.join() 方法 (主线程会休眠,等待子线程thread1运行结束后才会继续运行)

结果:无论运行多少次,结果都是按照我们的顺序执行的

原理:利用并发包里的Excutors的newSingleThreadExecutor产生一个单线程的线程池,而这个线程池的底层原理就是一个先进先出(FIFO)的队列代码中executor.submit依次添加了123线程,按照FIFO的特性执行顺序也就是123的执行结果,从而保证了执行顺序

这里的源码就多了,展开来太多了有兴趣的可以自行了解一下。面试答到这兩个就基本差不多了还有很多自定义的实现也可以做到同样的效果,这里也不做展开

我要回帖

更多关于 如何启动线程 的文章

 

随机推荐