- 前言
- 1 如何启动新的线程
- 1.1 实现Runnable接口,建立Runnable对象(线程任务)
- 1.2 建立Thread对象,并赋予Runnable
- 1.3 启动Thread
- 2 如何影响线程切换
- 3 线程的并发性问题
- 3.1 竞争状态问题
- 3.2 死锁问题
- 4 线程和进程的关系
线程相当于在Java的main函数之外开辟了一个新的执行空间,通过JVM在多个执行空间之间的快速切换,达到近似并发执行的目的。线程之间的切换和执行由JVM的线程调度器来决定,调度无法被控制,只能某种限度上被影响(Thread.sleep()方法),可以认为线程切换近似随机。
1 如何启动新的线程PS:也可以通过建立Thread的子类覆盖run()方法,来创建新的线程,但一般不这么做。
public class threadtest{
public static class TestThread extends Thread{
public void run() {
System.out.println("我是线程");
}
}
public static void main(String[] args) {
Thread thread = new TestThread();//实例化线程
thread.start();//启动线程
}
}
1.1 实现Runnable接口,建立Runnable对象(线程任务)
Runnable类必须实现Runnable接口及其下的run()函数,线程执行run()函数。
public class MyRunnbale implements Runnable{
public void run(){
System.out.println("I'm thread.");
}
}
public class Main{
public static void main(String[] args){
Runnable threadjob = new MyRunnable();
}
}
1.2 建立Thread对象,并赋予Runnable
public class MyRunnbale implements Runnable{
public void run(){
System.out.println("I'm thread.");
}
}
public class Main{
public static void main(String[] args){
Runnable threadjob = new MyRunnable();
Thread myThread = new Thread(threadjob);
}
}
1.3 启动Thread
myThread.start();2 如何影响线程切换
通过Thread.sleep()方法,让线程脱离执行状态,进入睡眠
public class MyRunnbale implements Runnable{
public void run(){
System.out.println("I'm thread.");
try{
Thread.sleep(2000);//强迫此线程离开执行中的状态,等待2s
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
3 线程的并发性问题
3.1 竞争状态问题
两个以上并发执行的线程存取单一对象的数据,此时即出现竞争状态问题
譬如,A用户和B用户同时对静态变量public static int num=1000进行检查和扣款操作,当num-want>=0时,允许扣款操作(want为期望扣款)。如果出现,当A检查余额满足后切换到了B,B完成了检查并扣款的操作,再切换到A,A认为余额满足需求,直接进行扣款操作,最终导致账户余额小于0。
解决方案:让方法原子化,对待存取的对象加“锁”,synchronized关键字
//该方法位于线程Runnable任务中
private synchronized void takemoney(int want){
if(num-want>0){
System.out.prinrln("OK.");
num = num - want;
}
}
通过synchronized关键字,锁住存取对象的方法,可以认为每个对象都有一个虚拟的锁和钥匙,当出现synchronized方法对其进行存取时,钥匙被该线程的方法拿走,在该方法执行完毕,释放钥匙之前,其他线程的所有同步化方法无法取得钥匙,即无法对该对象进行存取。
3.2 死锁问题当两个线程互相持有对方等待的同步化钥匙,在获得对方钥匙之前又不会释放当前持有的钥匙,此时陷入死锁,JAVA没有处理死锁的机制,所以在设计方法时必须避免死锁的出现。
4 线程和进程的关系以下内容参考互联网资源:
进程是操作系统中运行的一个任务(一个应用程序运行在一个进程中)。系统将一块包含了某些资源的内存区域分配给进程。进程中所包含的一个或多个执行单元称为线程。进程拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问。线程只能归属于一个进程并且它只能访问该进程所拥有的资源。当操作系统创建一个进程后,该进程会自动申请一个名为主线程或首要线程的线程,进程会默认执行该线程。
线程是进程的一个顺序执行流。同进程的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈,JVM中包括Java虚拟机栈和本地方法栈。线程在切换时负荷小,因此,线程也被称为轻负荷进程。一个进程至少有一个线程。一个进程可以包含多个线程。
线程的划分尺度小于进程,多线程程序的并发性高。线程在执行过程中与进程的区别在于每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能独立执行,必须存在应用程序中,由应用程序提供多个线程执行控制。
线程通常用于在一个程序中需要同时完成多个任务的情况,将每个任务定义为一个线程,是它们得以一同工作。也可以用于单一线程可以串行完成,但是使用多线程并行可以更快的情况,比如下载多个文件。
多个线程“同时”运行只是我们感官上的一种表现,事实上线程是并发运行的,OS将时间划分为很多时间片段,尽可能均匀分配给每一个线程,获取时间片段的线程被CPU运行,而其它线程全部等待。所以微观上是走走停停的,宏观上都在运行,这种现象叫并发,但是不是绝对意义上的“同时发生”。



