JAVA多线程之两个线程同时写⼀个⽂件
1.多线程
线程是程序执⾏流的最⼩单元。是进程中的⼀个实体,是被系统独⽴调度和分派的基本单位,线程⾃⼰不拥有系统资源,只拥有⼀点⼉在运⾏中必不可少的资源,但它可与同属⼀个进程的其它线程共享进程所拥有的全部资源。⼀个线程可以创建和撤消另⼀个线程,同⼀进程中的多个线程之间可以并发执⾏。由于线程之间的相互制约,致使线程在运⾏中呈现出间断性。线程也有就绪、阻塞和运⾏三种基本状态。就绪状态是指线程具备运⾏的所有条件,逻辑上可以运⾏,在等待处理机;运⾏状态是指线程占有处理机正在运⾏;阻塞状态是指线程在等待⼀个事件(如某个信号量),逻辑上不可执⾏。每⼀个程序都⾄少有⼀个线程,若程序只有⼀个线程,那就是程序本⾝。
多线程的意义就在于使得⼀个应⽤程序有多条执⾏路径,从⽽提⾼进程(程序)的执⾏效率。
2.JAVA中的多线程
2.1概述实现
JAVA实现多线程的⽅法有三种: 1)继承Thread实现多线程。2)通过实现Runnable接⼝⽅式实现多线程。3)使⽤ExecutorService、Callable、Future实现有返回结果的多线程。这三种⽅法的具体实现,在
此先不⼀⼀赘述,⽹上有很多有关的博客,不明⽩的朋友可以去看看。
JAVA程序的运⾏原理便是命令去启动JVM,JVM会启动⼀个进程,该进程会启动⼀个主线程。然⽽JVM的启动必然也是多线程的,⼀般情况下,它最低有两个线程启动了:主线程和垃圾回收线程。
2.2线程⽣命周期
1)新建 2)就绪 3)运⾏ 4)阻塞 5)死亡
2.3线程的优先级
线程的调度有两种⽅式:1)分时调度。2)抢占式调度。JAVA采⽤的是后者,默认情况下,线程去抢占资源(CPU执⾏权)。我们可以通过setPriority⽅法,设置线程的优先级,默认是5,范围为1-10。但是⼀般情况下,光是设置线程的优先级,不能使得线程有序且⾼效执⾏,所以我们还需要学习更多的⽅法与原理机制。
2.4线程的控制(常见⽅法)
1)休眠线程 2)加⼊线程 3)礼让线程 4)后台线程 5)终⽌线程
2.5多线程的安全问题
在多线程的环境下,⼤多时候都是会共享数据,存在多条语句操作共享数据,这样很多时候会出现脏数据。所以为了解决线程的安全的问题,我们可以通过synchronized同步锁对象达到我们的⽬的。
1)同步代码块
synchronized(对象)
{
需要被同步的代码块
}
2)同步⽅法
把同步加在⽅法上,这⾥的锁对象是this。
3)静态同步⽅法
把同步加在⽅法上。这⾥的锁是当前类的字节码⽂件。
PS:JDK5以后的针对线程的锁定操作和释放操作: Lock锁。
3.多线程写⼀个⽂件
如何实现多线程同时或读或写⼀个⽂件呢?我们都知道,⼀个⽂件在同⼀时间只能被⼀个线程读(写),如果要两个线程同时写⼀个⽂件,如何有效有序的分配这个临界资源呢?
下⾯我将通过⼀个例⼦,阐述我的解决⽅法 -——沉睡唤醒机制。
需求:两个线程写⼀个TXT⽂件,线程1:I love you 线程2:so do I 。保证线程1、2有序执⾏,⼀句I love you,对应⼀句so do I。第⼀步,先创建WRFile类。这⼀步是关键的。
package cn.Thread.love;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class WRFile {
//String str;
boolean flag;
public WRFile()
{
}
public synchronized void read1()
{
if(this.flag)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
RandomAccessFile ra = null;
try {
ra = new RandomAccessFile("", "rw");
ra.seek(ra.length());
ra.writeBytes("I love you");
ra.writeBytes("\r\n");
} catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
ra.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//修改标记唤醒线程
this.flag = true;
}
public synchronized void read2()
{
if(!this.flag)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
RandomAccessFile ra = null;
try {
ra = new RandomAccessFile("", "rw");
ra.seek(ra.length());
ra.writeBytes("so do I");
ra.writeBytes("\r\n");
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
ra.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//修改标记唤醒线程
this.flag = false;
}
}
第⼆步,创建我们的两个线程类,第⼀个FirstThread。
public class FirstThread implements Runnable { private WRFile wr = new WRFile();
public FirstThread(WRFile wr) {
this.wr = wr;
}
@Override
public void run() {
while(true)
{
}
}
}
第⼆个SecondThread
package cn.Thread.love;
public class SecondThrad implements Runnable{ private WRFile wr = new WRFile();
public SecondThrad(WRFile wr) {
this.wr = wr;
}
@Override
public void run() {
while(true)
{
}
}
}
第三步,main⽅法启动线程
public class LoveDemo {
public static void main(String[] args) {
//创建数据对象
WRFile wr = new WRFile();
//设置和获取类
FirstThread ft = new FirstThread(wr);
SecondThrad st = new SecondThrad(wr);
//线程类
Thread th1 = new Thread(ft);
Thread th2 = new Thread(st);
//启动线程
th1.start();
th2.start();
}
}
即可实现两个线程同时(有序)写⼀个⽂件,两个以上,或是其他操作也可参考这种思想去实现。有不对的地⽅,还望⼤神们,多多指教。
>一个线程可以包含多个进程
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论