打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
多线程编程

目录

1、什么是线程

2、线程的基本操

3、基本的线程同步操作

1.1 进程、线程概念:

1、进程:一个计算机程序的运行实例,有自己的独立地址空间。

2、线程:表示程序的执行流程,是CPU调度执行的基本单位;同一进程中的线程共用相同的地址空间。

线程状态

2.1线程状态:包括以下图中五种

 

3.1 创建线程的两种方式 

第一种方式:使用Runnable接口创建线程;

第二种方式:直接继承Thread类创建对象;

实例代码:

package creatthreadtwo;

public class MyThread1 extends Thread {

public void run(){

System.out.println("1");

}

public static void main(String[] args) {

MyThread1 mThread=new MyThread1();

mThread.start();

}

}

package creatthreadtwo;

public class MyThread2 implements Runnable {

@Override

public void run() {

System.out.println("1");

}

public static void main(String[] args) {

Thread mThread=new Thread(new MyThread2());

mThread.start();

}

}

4.1 常见的线程方法讲解:

1Thread.stop():不推荐使用stop方法来终止线程,它会释放所有的锁资源

实例代码:

package leranstop;


public class StopThread {

public static void main(String[] args) throws Exception {  

Thread thread = new Thread() {  

 @Override 

 public void run () {  

    try {  

    //子线程休眠1秒

     Thread.sleep(1000);

    } catch (InterruptedException e) {  

        //异常处理

   }  

    System.out.println ("此处代码不会执行");  

}  

 

};  

//启动线程

thread.start();  

//主线程休眠0.1秒

Thread.sleep(100);  

//子线程停止

thread.stop();  

 

}  

}

}

2、Thread.interrupt():该方法中断线程,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

而isInterrupted()通过中断手段在运行中来判断线程是否中断来终止线程,但是必须重设中断标志位。

实例代码:

package learninterrput;


public class Main {

public static void main(String[] args) {

         Main main = new Main();

         Thread t = new Thread(main.runnable);

         System.out.println("mainmainmain");

         t.start();

         try {

            Thread.sleep(2000);

         } catch (InterruptedException e) {

            e.printStackTrace();

         }

         t.interrupt();

         System.out.println("sososososo");

     }

 

     Runnable runnable = new Runnable() {

         @Override

         public void run() {

             int i = 0;

         try {

             while (i < 1000) {

                 Thread.sleep(200);

                 System.out.println(i++);

             }

             } catch (InterruptedException e) {

            e.printStackTrace();

             }

         System.out.println("子线程");

         }

    };

}

package learninterrput;

public class Main2 implements Runnable{
    
public static void main(String[] args) {
Main2 main = new Main2();
        Thread t = new Thread(main);
        System.out.println("mainmainmain");
        t.start();
        try {
            Thread.sleep(2000);
            t.interrupt();
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
        
        System.out.println("sososososo");
    }
   
    @Override
    public void run() {
int i = 0;
        while (i < 1000) {
        if(Thread.currentThread().isInterrupted()){
        return;
        }
            try {
            Thread.sleep(200);
                System.out.println(i++);
            }  catch (InterruptedException e) {
            System.out.println("重设中断标志位");
               Thread.currentThread().interrupt();
           }
        }
        System.out.println("运行结束");
   }
}

3suspend():线程挂起,阻塞状态,不会释放锁

4resume():线程继续执行执行

 


5join():当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join方法加入的join线程完成为止

6sleep():让当前正在执行的线程暂停一段时间并进入阻塞状态

实例代码:

package leranjoin;


import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import java.util.Random;


public class LeranJoin {

public static void main(String[] args) {

//t1产生10个随机数填充到list

//t2加入t1 等到t1线程完成以后对list进行排序

//在t2线程中  t1.join(),实现t2等待t1的结束

final List<Integer> list=new ArrayList<Integer>();

final Thread t1=new Thread(){

public void run(){

Random r=new Random();

for(int i=0;i<10;i++){

list.add(r.nextInt(100));

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("执行一次...");

}

}

};

final Thread t2=new Thread(){

public void run(){

System.out.println("t2 start...");

try {

t1.join();

} catch (InterruptedException e) {

e.printStackTrace();

}//当前线程等待t1结束

System.out.println("t1结束了");

Collections.sort(list);

System.out.println(list);

}

};

t1.start();

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

t2.start();

}

}

7yeild():它不会阻塞该线程,它只是将该线程转入就绪状态;当调用了yield方法后,只有优先级与当前线程相同,或者优先级比当前线程更高的就绪状态的线程才会获得

执行的机;设置线程优先级的方法---setPriority() 

实例代码:
package leranjoin;

public class LeranYeild {

public static void main(String[] args)
  {
     Thread producer = new Thread(){
     public void run()
      {
         for (int i = 0; i < 3; i++)
         {
            System.out.println("I am Producer : Produced Item " + i);
            Thread.yield();
         }
      }
     };
     Thread consumer = new Thread(){
     public void run()
      {
         for (int i = 0; i < 3; i++)
         {
            System.out.println("I am Consumer : Consumed Item " + i);
            Thread.yield();
         }
      }
     };
 
     producer.setPriority(Thread.MIN_PRIORITY); //Min Priority
     consumer.setPriority(Thread.MAX_PRIORITY); //Max Priority
     producer.start();
     consumer.start();
  }
}

8、setDaemon(true):设置守护线程,当一个java应用内,只有守护线程的时候,jvm就会自然退出。

实例代码:

package learnwaitornotifyordaemo;


public class DaemonDemo extends Thread{

public void run(){

while(true){

System.out.println("继续");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

DaemonDemo t=new DaemonDemo();

t.setDaemon(true);

t.start();

}

}

9wait():导致当前的线程等待,会释放其拥有的锁直到其他线程调用此对象的notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器(锁)。

10、notify():唤醒在此对象监视器上(锁)等待的单个线程。

11notifyAll():唤醒在此对象监视器上(锁)等待的所有个线程。

实例代码:

package learnwaitornotifyordaemo;


public class LeranwaitOrnotify {


final static Object object=new Object();

final static Object object2=new Object();

public static class T1 extends Thread{

public void run(){

synchronized (object) {

System.out.println("T1 start wait on object");

try {

object.wait();

System.out.println("T1 end");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public static class T2 extends Thread{

public void run(){

synchronized (object) {

System.out.println("T2 start notify all threads");

object.notify();

System.out.println("T2 end");

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public static class T3 extends Thread{

public void run(){

synchronized (object) {

System.out.println("T3 start wait one threads");

try {

object.wait();

System.out.println("T3 end");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public static void main(String[] args) {

Thread t1=new T1();

Thread t2=new T2();

Thread t3=new T3();

t1.start();

t3.start();

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

t2.start();

}

}

5.1 线程安全同步、异步

1、同步:就是指多个线程在逻辑上互有前因后果的关系,一个线程要等待上一个线程执行完之后才开始执行当前的线程

2、异步:是指一个线程去执行,它的下一个线程不必等待它执行完就开始执行

3、并发:在同一时间间隔内有多个线程在同时执行,就是线程的并发

实例代码:


6.1 线程安全同步机制

1、同步关键字:synchronized,对共享需要锁定的资源加上该关键字--即为同步监视器

1)、指定加锁对象;对给定对象加锁,进入同步代码块前要获得给定对象的锁

2)、对当前类加锁,进入同步代码块前要获得当前类的锁

3)、直接作用于实例方法;对当前实例加锁,进入同步代码块前要获得当前实例的锁直接作用于静态的方法;

实例代码:

package learnsynchonized;


public class MyThread extends Thread{

private int count=5;

    public synchronized void run(){

    count--;

    System.out.println(Thread.currentThread().getName()+"----count: "+count);

    }


public static void main(String[] args) {

MyThread t=new MyThread();

Thread t1=new Thread(t,"t1");

Thread t2=new Thread(t,"t2");

Thread t3=new Thread(t,"t3");

Thread t4=new Thread(t,"t4");

Thread t5=new Thread(t,"t5");

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

}

}

package learnsynchonized;

public class Tbleran implements Runnable{
    static Tbleran instance=new Tbleran ();
static int i=0;
@Override
public void run() {
for(int j=0;j<10000;j++){
synchronized (instance) {
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
//1、以下是实例的对象作为锁
Thread t1=new Thread(instance);
Thread t2=new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}

package learnsynchonized;

public class Tbleran2 implements Runnable{

static int i=0;
public static synchronized void increase(){
i++;
}
@Override
public void run() {
for(int j=0;j<10000;j++){
increase();
}
}
public static void main(String[] args) throws InterruptedException {
//2、以下是类作为锁
Thread t1=new Thread(new Tbleran2());
Thread t2=new Thread(new Tbleran2());
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
package learnsynchonized;

public class Tbleran3 implements Runnable {

static int i=0;
//锁加载在对象实例上
public  synchronized void increase(){
i++;
}
@Override
public void run() {
for(int j=0;j<10000;j++){
increase();
}
}
public static void main(String[] args) throws InterruptedException {
//2、以下是类作为锁
Thread t1=new Thread(new Tbleran3());
Thread t2=new Thread(new Tbleran3());
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}

2volatile:是JAVA中的轻量级的同步机制;注意:保证可见性,但不能保证原子性

实例代码:

package learnvolatile;


import java.util.concurrent.atomic.AtomicInteger;


public class AtomictyVolatile extends Thread{

public volatile int race = 0;  

    @Override  

    public void run() {  

        increase();  

    }  

    private synchronized void increase() {  //synchronized

        race ++;  

        System.out.println(race);  

          

    }  

    public static void main(String[] args) {  

    AtomictyVolatile t = new AtomictyVolatile();  

        Thread [] threads = new Thread[10];  

        for (int i = 0; i < 10; i++) {  

            threads[i] = new Thread(t);  

            threads[i].start();  

        }  

       

        //保证打印的时候1000个线程都已经执行完毕

    } 

}

package learnvolatile;

public class VisibilityVolatile  extends Thread{

private boolean isRunning=true;
private void setRunning(boolean isRunning){
this.isRunning=isRunning;
}
public void run(){
System.out.println("进入run方法....");
while(isRunning){
//
}
System.out.println("线程停止");
}
public static void main(String[] args) throws InterruptedException {
VisibilityVolatile vt=new VisibilityVolatile();
vt.start();
Thread.sleep(3000);
vt.setRunning(false);
System.out.println("isRunning 已经被置为 false");
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(vt.isRunning);
}
}

3lock显示加锁,进行同步:java也可以用Lock显示的对临界区代码加锁以及解锁

实例代码:

package leranlock;


import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;


import learnsynchonized.MyThread;


public class MyLock implements Runnable{


private int count=5;

private Lock lock=new ReentrantLock();

//private ReadWriteLock rwLock=new ReentrantReadWriteLock();

    public  void run(){

    lock.lock();

    try{

    count--;

    System.out.println(Thread.currentThread().getName()+"----count: "+count);

    }catch(Exception e){

    //DOTO

    }finally{

    lock.unlock();

    }

    }


public static void main(String[] args) {

MyLock t=new MyLock();

Thread t1=new Thread(t,"t1");

Thread t2=new Thread(t,"t2");

Thread t3=new Thread(t,"t3");

Thread t4=new Thread(t,"t4");

Thread t5=new Thread(t,"t5");

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

}

}

7.1 线程安全 脏读、线程池

1脏读:就是一个线程的所访问的资源没处理完成,另一个线程过来访问这些资源,就会导致脏读,如读写线程操作等。

实例代码:

package learndirtyread;


public class DirtyRead{


private String username="bjsxt";

private String password="123";

public synchronized void setValue(String username,String password){

this.username=username;

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

this.password=password;

System.out.println("setValue 最终结果为: username= "+username+",password= "+password);

}

public synchronized void getValue(){

System.out.println("getValue 方法得到结果为: username= "+username+",password= "+password);

}

public static void main(String[] args) {

final DirtyRead dd = new DirtyRead();

Thread t1=new Thread(new Runnable(){

@Override

public void run() {

dd.setValue("zs", "456");

}

});

t1.start();

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

dd.getValue();

//System.exit(1);

}

}

2、线程池

线程池:JDK提供一套线程框架Execute,来管理线程,通过Execute创建特定功能的线程池方法。

优点:

a. 重用存在的线程,减少对象创建、消亡的开销,性能佳

b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞

c. 提供定时执行、定期执行、单线程、并发数控制等功能

实例代码:

package leranthreadpool;


import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class ThreadPool {


/**

* 1)、创建两个固定数量线程的线程池

* 2)、为线程提交10个工作任务

* 3)、每个任务每隔一秒输出1,2,3,并输出线程名

* concurrent:并发包下的

* 测试结果:只有两个线程并发执行

* Executors 是ExecutorService工厂

*/

public static void main(String[] args) {

ExecutorService pool=Executors.newFixedThreadPool(2);

//创建任务交给线程池执行(execute : 执行)

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

pool.execute(new Task());

}

}

/**

*交给线程池执行的任务必须实现  Runnable 接口

*/

   class Task implements Runnable{


@Override

public void run() {

Thread t=Thread.currentThread();

try {

System.out.println(t.getName()+":1");

Thread.sleep(500);

System.out.println(t.getName()+":2");

Thread.sleep(500);

System.out.println(t.getName()+":3");

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

8.1 线程安全 消息队列、模式

1、在并发队列上JDK提供了两套实现,一个是ConcurrentLinkedQueue为代表的高性能队列,一个是BlockingQueue为接口的阻塞队列,都继承Queue

2、模式future模式,master-work模式,生产者--消费者模式。

实例代码:

package xchengreadfile;


public class MyThread implements Runnable {

@Override

public void run() {

System.out.println("1");

}

public static void main(String[] args) {

Thread mThread=new Thread(new MyThread());

mThread.start();

}

}

package xchengreadfile;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ThreadReadDemo {

/**
* 先读后写的操作,先将文件内容读到list中然后通过放入队列写入另一个文件中
* 读:两个线程读操作
* 写:10个线程写的操作
*/
public static void main(String[] args) {
Thread t1=new Thread(new MultiThread());
Thread t2=new Thread(new MultiThread());
t1.start();
t2.start();
}

}

class MultiThread implements Runnable{
    public static BufferedReader br=null;
    public List<String> list =new ArrayList<String>();
    
public List<String> getList() {
return list;
}

public void setList(List<String> list) {
this.list = list;
}
static{  
        try {  
            br = new BufferedReader(new FileReader("E://ceshi.txt"),10);  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        }  
    }  

@Override
public void run() {
String line=null;
int count=0;
while(true){
synchronized (br) {
try {
while((line=br.readLine())!=null){
if(count<6){
this.list.add(line);
count++;
}else{
this.list.add(line);
count=0;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
display(this.list);
if(line==null){
break;
}
}
}
public void display(List<String> list){
for(String str:list){
System.out.println(str);
}
System.out.println(list.size());
}
}

class getList{
}

package xchengreadfile;


import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class ThreadReadDemo2 {


/**

* @param args

*/

public static void main(String[] args) {

int count=getLineInt();

ExecutorService pool=Executors.newFixedThreadPool(5);

for(int i=0;i<10;i++){

pool.execute(new Task());

}

}

public static int getLineInt(){

int x=0;

try {

FileReader fr = new FileReader("E://ceshi.txt");

BufferedReader br = new BufferedReader(fr);

while(br.readLine()!=null){

x++;

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return x;

}


}


class Task extends Thread{

}


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
java中,如何安全的结束一个正在运行的线程?
计算机是如何工作的,Java多线程编程
java多线程、线程池的实现
深入理解Java并发之synchronized实现原理
Java并发之线程中断
Thread详解2:停止与中断
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服