Java中的线程
线程是进程当中的一个执行流程
多进程:在OS中能(同时)运行多个任务(程序)。
多线程:在同一应用程序中有多个顺序流(同时)执行。
线程也是个对象,线程类生成线程对象
创建线程的方法
- 定义一个线程类,它继承类Thread并重写其中的方法run(),方法run()称为线程体。
由于Java只支持单继承,用这种方法定义的类不能再继承其他类。
多线程执行无规律可循。
class FirstThread extends Thread{
public void run(){
for(int i = 0; i < 10; i++){
System.out.println("FirstThread--->" + i);
}
}
}
Test类中:
//test类中存在三个线程,主函数main(),ft.start()线程,垃圾回收线程。
public static void main(String args[]){
//生成线程类的对象,ft是thread对象。对应new环节
FirstThread ft = new FirstThread();
//启动线程
ft.start();//线程进入就绪状态,与主线程进行抢占CPU
for(int i = 0; i < 10 ; i++){
System.out.println("main--->" + i);
}
}
实现线程的第二种(用的多)
提供一个实现接口Runnable的类作为线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,
把目标对象传递给这个线程实例,由该目标对象提供线程
class RunnableImple implements Runnable{
public void run(){
for(int i = 0; i< 100; i++){
System.out.println("RunnableImple--->" + i);
if(i == 50){
//在执行到RunnableImple50时,停住2000毫秒
try{
Thread.sleep(2000);
}
catch(Exception e){
System.out.println(e);
}
}
}
}
}
Test中:
class Test{
public static void main(String args[]){
//生成一个Runnable接口实现类的对象
RunnableImple ri = new RunnableImple();
//生成一个Thread对象,并将Runnable接口实现类的对象作为参数
//传给该Thread对象
Thread t = new Thread(ri);
//通知Thread对象执行Start()方法
t.start();
//getPriority()获取优先级,打印出默认的优先级为5,
//可用Thread提供的静态常量来设置线程的优先级
//优先级越高,执行的概率越高
System.out.println(t.getPriority());
t.setPriority(Thread.MAX_PRIORITY);
System.out.println(t.getPriority());
t.setPriority(Thread.MIN_PRIORITY);
System.out.println(t.getPriority());
}
}
相对优点:都是对Run()方法进行复写。
实现的是接口,尽量少用继承。实现了线程体和执行线程拆分开。
控制线程的常见的函数
中断线程
1.Thread.sleep(n),执行它,当前线程进行休眠状态,让出CPU,2000毫秒过后,醒来继续和其他进行争夺CPU
2.Thread.Yield(),当线程运行到这行代码时,(此刻线程正在占用着CPU)自动让出CPU。
然后再重新抢夺......设置线程的优先级
getPriority()获取优先级, setPriority(),设置优先级
多线程数据安全
class MyThread implements Runnable{
int i = 100;
public void run(){
while(true){
//this相当于一个锁,进入后必须执行完成当前代码块
synchronized(this){
//Thread.currentThread(),静态方法。获取当前代码正在那个代码中运行
System.out.println(Thread.currentThread().getName()
+ i);
i--;
Thread.yield();
if(i < 0){
break;
}
}
}
}
}
Test类:
class Test{
public viud main(String args[]){
MyThread myThread = new MyThread();
//生成两个Thread对象,但共用一个线程体
//共用一个i,同一个整形变量
Thread t1 = new Thread(myThread);
Thread t2 = new Thread(myThread);
t1.setName("线程a");
t2.setName("线程b");
t1.start();
t2.start();
}
}
39.深入synchronized关键字
同步代码块
class MyThread1 implements Runnable{
private Service service;
public MyThread1(Service service){
this.service = service;
}
public void run(){
service.fun1();
}
}
Service类:
class Service{
public void fun1(){
synchronized(this){
try{
Thread.sleep(3 * 1000);
}
catch(Exception e){
System.out.println(e);
}
System.out.println("fun1");
}
}
public void fun2(){
synchronized(this){
System.out.println("fun2");
}
}
}
Test类:
class Test{
public static void main(String args[]){
Service service = new Service();
Thread t1 = new Thread(new MyThread1(service));
Thread t2 = new Thread(new MyThread2(service));
//线程1执行时,this代表的是传入的service。
//线程1在休眠时,线程2同样不能执行。因为同一个service
//同步锁锁住不是代码块,
//一旦一个线程获得了一个对象service的同步锁,
//那么这个对象下边的其他的同步的代码都是不能够被其他线程执行的。
//需要等待同步锁被释放之后才可执行。
t1.start();
t2.start();
}
}
同步方法类似于同步代码块:同步方法锁住的是this,是调用的函数的那个对象
public synchronized void fun1()