线程的概念
程序:是为完成特定任务,用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象。
进程:是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程,有它自身的产生,存在和消亡的过程。-------生命周期
线程:进程可进一步细化为线程,是一个程序内部的一条执行路径
并行:多个CPU同时执行多个任务
并发:一个CPU(采用时间片)同时执行多个任务,比如秒杀平台,多个人做同件事
Thread创建
- 继承Thread类线程序
- 实现Runnable接口创建线程
- 使用Callable和Future创建线程
- 使用线程池例如Executor框架
1.继承Thread类
创建线程
class LTThread extends Thread{
@Override
public void run(){
//必须重写run方法
for (int i = 0; i < 101; i++) {
System.out.println("我是新线程");
}
}
}
用start方法创建线程,调用run不会开启线程
start后线程不是马上开始,而是等待CPU有空闲时间时开始
public class Main {
public static void main(String[] args) {
LTThread ltThread=new LTThread();
ltThread.start();
}
}
介绍几个方法
1.setName()方法,为线程创建名字,必须在start前,否则无效。如果不set就有系统分配
2.getName()方法,返回线程名字。
3.setPriority()方法,设置优先级,这里set的是Java虚拟机中的优先级,调用时候不一定完全按照这个。只能作为调度的参考。
4.可以重写构造方法setName
2.Runnable接口创建线程
import java.util.*;
class T2 implements Runnable{
public int a=100;
@Override
public void run(){
for (int i = 0; i < 10; i++){
System.out.println(Thread.currentThread().getName()+":"+a--);
}
}
}
public class Main {
public static void main(String[] args) {
T2 t2=new T2();
Thread thread=new Thread(t2,"new");
thread.start();
Thread thread1=new Thread(t2,"new1");
thread1.start();
}
}
3.Callable
import java.awt.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
class T3 implements Callable<Integer>{
@Override
public Integer call() throws Exception{
System.out.println(Thread.currentThread().getName());
int sum=0;
for (int i = 0; i < 11; i++) {
sum+=i;
}
return 0;
}
}
public class Main {
public static void main(String[] args) {
T3 t3=new T3();
FutureTask<Integer> futureTas=new FutureTask<Integer>(t3);
//只有一格线程执行
Thread thread=new Thread(futureTas,"test1");
thread.start();
Thread thread1=new Thread(futureTas,"test2");
thread1.start();
// System.out.println(futureTas.get());
}
}
3.特殊创建方法
1.匿名内部类实现
2.lambda表达式实现
import java.util.*;
public class Main {
public static void main(String[] args) {
//匿名内部类实现
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是新的线程");
}
}).start();
//lambda表达式创建
new Thread(()->{
System.out.println("I am newThread");
}).start();
}
}
3.继承Thread
import java.util.*;
public class Test extends Thread{
public static void main(String[] args) {
Test test =new Test();
test.start();
}
@Override
public void run() {
System.out.println("new Thread");
}
}
4.继承Runnable接口
import java.util.*;
public class Test implements Runnable{
public static void main(String[] args) {
Test test=new Test();
Thread t1=new Thread(test);
t1.start();
}
@Override
public void run(){
}
}
Thread类中的常见方法
1.start()方法
启动线程,使得线程处于就绪态,还没有获得cpu使用权力。等待cpu
2.yield()
让线程回到就绪态。这样可以让其他线程更有机会获得cpu
3.currentThread(),返回当前线程
4.sleep()
在指定的毫秒数里面让当前正在执行的线程休眠等到休眠时间结束。从阻塞到就绪态。
5.join()
表示一定要该运行线程执行结束以后才能开始其他线程
6.wait()
7.notify()
线程同步-可见性
volite关键词
synchronized实例
同步
import java.util.*;
class T1 implements Runnable{
//锁对象--当前实例对象
//static对类要锁
synchronized public void f1() {
System.out.println(Thread.currentThread().getName() + "开始了");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"结束了");
}
@Override
public void run(){
f1();
}
}
public class Test {
public static void main(String[] args) {
T1 t=new T1();
T1 tt=new T1();
Thread t1=new Thread(t,"测试1");
Thread t2=new Thread(t,"测试2");
Thread t3=new Thread(tt,"测试3");
t1.start();
t2.start();
t3.start();
}
}
synchronized缺点
- 效率低
- 锁的释放情况少,只在程序正常执行和抛出异常时释放锁
- 试图获得锁时不能设置超时
- 不能中断一个正在试图获得锁的线程
- 无法知道是否成功获得锁
lock接口和ReentrantLock类
Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要程序员手动释放锁,用try语句,最后在finally从句中释放锁
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
class T2 implements Runnable{
//
ReentrantLock reentrantLock=new ReentrantLock();
public void f1() {
reentrantLock.lock();
try {
System.out.println(Thread.currentThread().getName() + "开始了");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束了");
}
finally {
reentrantLock.unlock();
}
}
@Override
public void run(){
f1();
}
}
public class Test {
public static void main(String[] args) {
T2 t2=new T2();
Thread thread=new Thread(t2,"测试1");
thread.start();
Thread thread1=new Thread(t2,"测试2");
thread1.start();
}
}
结束语
最后还有一些东西没学,就不写了,什么线程池之类的。就自己看看了,有时间补充吧。