线程
线程和进程
线程:线程就是一条执行线索,多个线程是并发的运行着。
进程:是一个运行在内存中的程序,它有一块独立的内存空间。一个进程可能包含一个或多个线程。
Java当中的main函数就是一个主线程,迅雷下载是多线程的。
线程的创建方式
继承Thread类
1、继承Thread类
2、重写run方法(线程在执行的时候就是在执行线程类中的run方法中的代码)
3、创建线程对象
4、调用start方法
//1、继承Thread类
public class ThreadDemo1 extends Thread{
int i;
int j=0;
public ThreadDemo1(int i){
this.i = i;
}
// 2、重写run方法(线程在执行的时候就是在执行线程类中的run方法中的代码)
@Override
public void run() {
for (; j < 20; j++) {
System.out.println(i + "hello" + Thread.currentThread().getName() + ":" +j);
}
}
public static void main(String[] args) {
// 3、创建线程对象
ThreadDemo1 c = new ThreadDemo1(1);
ThreadDemo1 c2 = new ThreadDemo1(1);
// 4、调用start方法
c2.start();
c.start();
}
}
实现Runnable接口
1、实现Runnable接口
2、重写run方法
3、创建线程对象(Thread),并且传入Runnable对象
4、在通过线程对象调用start方法
//Runnable更容易的实现数据共享
//1、实现Runnable接口
public class ThreadDemo2 implements Runnable{
int i;
int j = 0;
public ThreadDemo2(int i){
this.i = i;
}
// 2、重写run方法
@Override
public void run() {
for (; j < 20; j++) {
System.out.println(i + "hello" + Thread.currentThread().getName() + ":" + j);
}
}
public static void main(String[] args) {
// 3、创建线程对象(Thread),并且传入Runnable对象
ThreadDemo2 c = new ThreadDemo2(1);
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
// 4、在通过线程对象调用start方法
t1.start();
t2.start();
}
}
实现Callable接口
1、实现Callable接口(需要定义返回值类型),重写call方法(需要抛出异常)
2、创建实现Callable接口的对象
3、建执行服务,提交执行,获取结果
4、关闭服务
public class MyThread implements Callable {
//重写Callable接口
@Override
public Object call() throws Exception {
return "重写call方法";
}
public static void main(String[] args) throws ExecutionException, InterruptedException, ExecutionException {
//创建实现Callable接口的对象
MyThread mythread = new MyThread();
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(1);
//提交执行
Future<String> result = service.submit(mythread);
//获取结果
String serviceresult = result.get();
//输出返回结果
System.out.println(serviceresult);
//关闭服务
service.shutdownNow();
}
}
创建线程池
1、创建线程池
2、调用execute方法并传入参数(Runnable或Thread接口对象)来启动线程
3、关闭服务
public class MyThread2 {
public static void main(String[] args) {
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(1);
//调用execute方法启动线程
service.execute(()-> System.out.println("创建线程池启动线程"));
//关闭服务
service.shutdown();
}
}
synchronized
三个窗口卖票
//Runnable更容易的实现数据共享
//synchronized 同一时刻只能允许一个线程进入
//1、实现Runnable接口
public class ThreadDemo4 implements Runnable{
private int i = 100;
Object obj = new Object();
// 2、重写run方法
@Override
public void run() {
sell();
}
//在方法上声明synchronized锁
public synchronized void sell(){
try {
while (i > 0){
i--;
int j =100-i;
System.out.println("当前已售出"+j+"张票;" + "还剩下"+i+"张票;" + Thread.currentThread().getName() );
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 3、创建线程对象(Thread),并且传入Runnable对象
ThreadDemo4 c = new ThreadDemo4();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
Thread t3 = new Thread(c);
//优先级默认是5,范围设置是0-10,优先级设置以后,并不代表这个线程一定会优先执行,它只是多了一个优先权
t2.setPriority(10);
t1.setName("线程1");
t2.setName("线程2");
t3.setName("线程3");
// 4、在通过线程对象调用start方法
t1.start();
t2.start();
t3.start();
}
}
死锁
待定。。。。
参考:
Java创建线程的四种方式