多线程的三种创建方式:
1:继承Thread,重写run()方。
Public class MyTHread extends Thread{
@Override
public void run(){
}
}
开启线程:
public class demo1 {
public static void main(String[] args) {
//开启线程
//1.创建对象
MyThread myThread = new MyThread();
//修改名字
myThread.setName("线程一");
myThread.start();//开启线程,run方法可以调用,但不是开启线程
//main方法也是线程
for (int i = 0; i < 5; i++) {
System.out.println("b"+i);
}
//第二个线程,
MyThread myThread2 = new MyThread();
myThread2.start();
}
}
2:实现Runnable接口,重写run()方法。
public class MyRun implements Runnable{
@Override
public void run() {
}
}
开启线程:
public class demo2 {
public static void main(String[] args) {
//开启线程
//1.创建对象
MyRun myRun = new MyRun();
Thread thread = new Thread(myRun,"线程名字");//跟第二个参数也可以修改名字
thread.setPriority(10);//设置线程优先级,数字越大优先级越高,但是不一定
thread.start();
//main方法也是线程
for (int i = 0; i < 34; i++) {
System.out.println("b"+i);
}
}
}
3:实现Callable接口,重写call()方法,Callable<>泛型里面写返回值的类型。
public class MyCall implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum =0;
for (int i = 1; i <= 100; i++) {
sum+=i;
}
return sum;
}
}
开启线程
public class demo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//开启线程
//1.创建对象
MyCall myCall = new MyCall();
//2.创建一个FutureTask对象,将mycall 传入
FutureTask<Integer> integerFutureTask = new FutureTask<>(myCall);
//3.创建thread对象,将FutureTask对象传入
Thread thread = new Thread(integerFutureTask);
//4.执行线程
thread.start();
//5.得到返回值
Integer integer = integerFutureTask.get();
System.out.println("integer = " + integer);
}
}
三种方法的优点缺点:
继承Thread:
优点:编程简单,可以直接使用Thread类中的方法,
缺点:扩展性比较差,不能继承其他类
实现Runnable,Callable接口:
优点:扩展性强,实现该接口的同时还可以继承其他类,
缺点:编程相对复杂,不能直接使用Thread方法。
其中实现Callablke接口有返回值。实现Runnable接口开启线程的时候可以传入第二个参数(线程名字),
线程名字修改与获取:
getName()获取名字,setName()修改名字,实现Runnable接口可以在第二个参数直接更改名字。
线程休眠:
Thread.sleep(10000);//当前线程休眠十秒
同步代码块:synchronized
格式:
synchronized(任意对象){
多条语句操作共享数据的代码
}
synchronized(任意对象)相当于给代加锁了。
好处:解决了多线程的数据安全问题。
弊端:当线程多的时候,因为每个线程都会判断同步上的锁,很耗费资源,会降低程序的运行效率。
同步方法:就是把synchronized关键字加到方法上
格式:调用就行了
//同步方法
public synchronized void method(){
}
不加static锁对象就是this
前面加static是静态的方法,对象就是类名.class
Lock锁:上锁:lock.lock();关锁:lock.unlock();
public class Lock1 implements Runnable{
private Integer number = 10;
//lock锁
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
//上锁
lock.lock();
if (number>0){
System.out.println(Thread.currentThread().getName()+"卖票了"+number);
number--;
}
//开锁
lock.unlock();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}