线程和进程:
进程指内存中运行的应用程序,每个进程都有独立的内存空间
线程是进程中的执行路径,共享一个内存空间,线程之间自由切换,并发执行,一个进程最少有一个线程,线程是在进程基础上进一步划分,一个进程启动后里面的若干路径可以划分为若干线程。
创建线程的三种方式;
第一种继承Thread类:run()方法是线程要执行的任务方法,start()方法用来启动线程
public static void main(String[] args) {
MyThread2 mt=new MyThread2();
Thread t=new Thread(mt);
t.start();
}
}
class MyThread2 extends Thread{
public void run(){
System.out.println("创建线程");
}
第二种是实现Runnable接口:
public static void main(String[] args) {
MyThread2 mt=new MyThread2();
Thread t=new Thread(mt);
t.start();
}
}
class MyThread2 implements Runnable{
public void run(){
System.out.println("创建线程");
}
第三种是实现Callable<>接口,与FutrueTask连用
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable mc=new MyCallable();
FutureTask<Integer> ft=new FutureTask<>(mc);
Thread t=new Thread(ft);
t.start();//子线程开始执行
```class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
for(int i=0;i<10;i++){
System.out.println(i);
Thread.sleep(100);
}
return 300;
}
}
实现 Runnable 与 继承 Thread 相比有如下优势:**
通过创建任务的方式,然后给线程分配任务来实现多线程,更加适合多个线程同时执行相同任务的情况
可以避免单继承带来的局限性,任务与线程本身分离,提高了程序健壮性。
设置当前线程名称: Thread.currentThread().setName(“111”);
获取当前线程名称: Thread.currentThread().getName();
中断线程interrupt()
如果该线程阻塞的调用wait() , wait(long) ,或wait(long, int)的方法Object类,或的join() , join(long) , join(long, int) , sleep(long) ,或sleep(long, int) ,这个类的方法,那么它的中断状态将被清除,并且将收到InterruptedException 。 如果在InterruptibleChannel上的I / O操作中阻止该线程,则通道将关闭,线程的中断状态将被设置,线程将收到ClosedByInterruptException 。
用户线程和守护线程:
当一个进程不包含任何的存活的用户线程时,进程就结束
守护线程:守护用户线程,当最后一个用户线程结束时,所有的守护线程都自动死亡(骑士与公主的关系)线程调用setDaemon(boolean on)方法。如果参数为 true ,则将此线程标记为守护程序线程,把线程设置为守护线程,需要在start();方法之前设置。
实现线程安全有三种方式:
第一种同步代码块
以售票为例子:
public static void main(String[] args) {
//一个任务三个线程执行
MyThread2 mt=new MyThread2();
Thread t=new Thread(mt);
Thread t2=new Thread(mt);
Thread t3=new Thread(mt);
t.start();
t2.start();
t3.start();
}
}
class MyThread2 implements Runnable{
int count=10;
boolean flag=true;
byte[] b=new byte[0];
public void run(){
while (flag){
synchronized (b){
syn();
}`
public void syn(){
if(count>0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+"余票"+count);
}else {
flag=false;
}
}
第二种: 同步方法
public synchronized boolean syn(){//方法上添加synchronized
if(count>0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+"余票"+count);
return true;
}
return false;
}
public static void main(String[] args) {
//一个任务三个线程执行
MyThread2 mt=new MyThread2();
Thread t=new Thread(mt);
Thread t2=new Thread(mt);
Thread t3=new Thread(mt);
t2.start();
t.start();
t3.start();
}
}
class MyThread2 implements Runnable{
int count=10;
public void run(){
while (true){
boolean s = syn();
if(s==false){
break;
}
}
}
第三种:Lock锁机制, 通过创建Lock对象,采用lock()加锁,unlock()解锁,来保护指定的代码
class MyThread2 implements Runnable{
int count=10;
Lock l=new ReentrantLock(true);//创建lock对象
public void run(){
while (true){
l.lock();//加锁
if(count>0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+"余票"+count);
}else {
break;
}
l.unlock();//解锁
}
}
线程分为六种状态:Thread state
- new 没启动的状态
- Runnable 运行时
- blocked 阻塞,排队时,排完队回到运行状态
- waiting 无限期等待状态,可以被其他线程唤醒,醒了回到运行状态
- timed waiting 指定时间的等待
- terminated 结束