栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java小记 多线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java小记 多线程

这两篇文章写得真的好:

  • Java多线程学习(吐血超详细总结)
  • 深入理解Java并发之synchronized实现原理

文章目录
  • 两种实现方式:
    • 继承`Thread`类
    • 实现`Runnable`接口
  • 线程的生命周期
  • 线程的加入 join()
  • 线程让步
  • 线程的优先级 setPriority()
  • 线程同步
    • 线程同步机制
    • 同步块 synchronized
    • 同步方法 synchronized
    • synchronized 具体应用
      • 1. 作用于实例方法
      • 2. 作用于静态方法
      • 3. 同步代码块


两种实现方式:
  • 继承Thread类
  • 实现Runnable接口

继承Thread类
构造Thread实例

  - public Thread()
  - public Thread(String threadName) 创建名为 ThreadName 的线程对象
public class Test extends Thread
{
	private int count=10;
	public void run(){
		while(true){
			System.out.printlnl(count + "");
			if(--count==0){
				return;
			}
		}
	}
	public static void main(String[] args){
		new Test().start();
	}
}
  • 实现线程的代码写在run方法中
  • 调用start方法执行线程(调用run()方法)
  • 主方法调用start方法前,Thread对象仅是一个实例,并不是线程

实现Runnable接口
实现Runnable接口语法:
public class Thread Extends Object implements Runnable

构造方法:
public Thread(Runnable target)
public Thread(Runnable target, String name)
  于是实现了将Runable实例与Thread实例相关联

使用Runnable接口启动新线程的步骤如下:

  • 建立Runnable对象
  • 使用参数为Runnable对象的构造方法创建Thread实例
  • 调用start方法启动线程
Thread t = new Thread(new Runnable(){
				public void run(){
					while(..){
					...
					}
				}
t.start();

线程的生命周期
状态说明
出生start()调用之前都处于出生状态
就绪调用start()后,就绪
运行线程得到系统资源后,运行
等待调用wait(),等待。调用notify()唤醒
休眠调用sleep()后,休眠
阻塞运行时发出输入、输出请求,阻塞
死亡run()执行完毕后,死亡
  • 使线程进入就绪状态
  • sleep()
  • wait()
  • 等待输入、输出完成

  • 使线程由就绪到运行
  • notify()
  • notifyAll() 唤醒所有等待状态线程
  • interrupt()
  • 休眠时间结束
  • 输入、输出结束

线程的加入 join()
  • 某线程使用join()方法加入另一线程时,另一线程会等待该线程执行完毕再执行。
Thread threadA = new Thread(new Runnable(){
						int count=0;
						public void run(){
							while(true){
							...
							threadB.join();
							}
						}
					}

线程让步
  • Thread.yield()方法。暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。

线程的优先级 setPriority()
  • 新线程继承父类优先级
  • 优先级1-10
常数优先级
Thread.MAX_PRIORITY10
Thread.MIN_PRIORITY1
Thread.NORM_PRIORITY5
Thread thread_a = new Thread();
setPriority("thread_a", 5, thread_a);
thread_a.setPriority(5);
thread_a.setName(name);	//设置线程名字

线程同步
  • 线程同步机制——解决资源访问冲突
线程同步机制
同步块 synchronized
  • 把共享资源放在同步块(临界区)
synchronized(Object){
}

同步方法 synchronized
  • 必须将每个能访问共享资源的方法修饰为synchronized
synchronized void func(){
}
public synchronized void doit(){
	if(num>0){
		try{
			Thread.sleep(10);
		}catch(Exception e){
			e.printStackTrace();
		}
		System.out.println("tickets" + --num);
	}
}
public void run(){
	while(true){
		doit();
	}
}

synchronized 具体应用
  • 实例方法
  • 静态方法
  • 同步代码块

1. 作用于实例方法
public class Test implements Runnable{
    //共享资源/临界资源
    static int i=0;


    // synchronized 修饰实例方法
    public synchronized void increase(){
        i++;
    }
    @Override
    public void run() {
        for(int j=0;j<1000;j++){
            increase();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Test instance=new Test();
        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }
}

输出:
>>> 2000

  • 如果实例不同,那就是不同的实例方法,谁也锁不着谁了。
public static void main(String[] args) throws InterruptedException {
    Thread t1=new Thread(new Test());
    Thread t2=new Thread(new Test());
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(i);
}

2. 作用于静态方法
public class Test implements Runnable{
    static int i=0;

	// 作用于静态方法,锁是当前class对象
    public static synchronized void increase(){
        i++;
    }

	// 非静态,访问时锁不一样(实例对象不一样) 不会 发生互斥
    public synchronized void increase4Obj(){
        i++;
    }

    @Override
    public void run() {
        for(int j=0;j<1000000;j++){
            increase();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //new新实例
        Thread t1=new Thread(new Test());
        //new另一个实例
        Thread t2=new Thread(new Test());
        //启动线程
        t1.start();t2.start();
        t1.join();t2.join();
        System.out.println(i);
    }
}
  • 作用于静态方法,就不用但是实例对象不一样的问题了。

3. 同步代码块
public class Test implements Runnable{
    static Test instance=new Test();
    static int i=0;
    @Override
    public void run() {
        //...do something...
        //锁对象为instance
        synchronized(instance){
            for(int j=0;j<1000000;j++){
                    i++;
              }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();t2.start();
        t1.join();t2.join();
        System.out.println(i);
    }
}

  • 实例对象锁【同上】
public static void run(){
	synchronized(this){
		for(...){
		...
		}
	}
}
  • class对象锁
public static void run(){
	synchronized(Test.class){
		for(...){
		...
		}
	}
}
import static java.lang.System.out;
import java.util.*;
import Tools.Tools;

// 同步代码块
public class TrySome implements Runnable{
	// 用于 run() for循环中累加
    static int value = 0;
   	// 计算 list 中数值求和
    static int sum=0;
    // 记录 list 中最大、最小值
    static double max=0, min=Double.POSITIVE_INFINITY;
    // 创建一 int ArrayList
    static List list = new ArrayList<>();
    // 这是自己编写的一个简单工具类
    static Tools tool = new Tools();

    private String name="None";
    private String say="None";
	
	// 构造方法
    public TrySome(String name, String words)
    {
        this.name = name;
        this.say = words;

    }
    public TrySome(){}

	// run() 方法
    public void run()
    {
        out.println("I am " + name + ".   I say: " + say);
        synchronized(TrySome.class){
            for(int i=0;i<2e5;i++)
            {
                value++;
            }
            mk_list();
            Iterator itr = list.iterator();
            while(itr.hasNext())
            {
                int data = itr.next();
                sum += data;
                if(data>max)
                {
                    max = data;
                }
                if(data 
import static java.lang.System.out;
import java.util.*;
import Tools.Tools;

public class FurtherM implements Runnable{
    List list = new ArrayList<>();
    static double sum=0;
    static List summ = new ArrayList<>();
    static Tools t = new Tools();
    String name;
    public FurtherM(List lst, String name)
    {
        list = lst;
        this.name = name;
    }
    public void run()
    {
        Iterator itr = list.iterator();
        synchronized(FurtherM.class)
        {
            while(itr.hasNext())
            {
                sum += itr.next();
            }
        }
        out.println(name + "   is over!");

    }

    public static List mk_list()
    {
        List lst = new ArrayList<>();
        double sumall=0;
        for(int i=0;i<40;i++)
        {
            double data = t.randf_format(1, 1, 40);
            sumall += data;
            lst.add(data);
        }
        summ.add(sumall);
        out.println(sumall);
        return lst;
    }

    public static void main(String[] args) throws InterruptedException
    {
        Thread t1 = new Thread(new FurtherM(mk_list(), "One"));
        Thread t2 = new Thread(new FurtherM(mk_list(), "Two"));
        t1.start();t2.start();
        t1.join();t2.join();
        out.println("sum: " + sum);
        out.println("allsum:  " + (summ.get(0) + summ.get(1)));
    }
}

Tools

import java.text.DecimalFormat;
import java.util.Date;
import java.util.Random;


public class Tools {
    Date d = new Date();
    int seed = Integer.parseInt(String.format("%ts", d));
    Random r = new Random(seed);
    DecimalFormat myFormat = new DecimalFormat();


    public void print(String s) {
        System.out.println(s);
    }

    public void print(Number... a) {
        StringBuilder s = new StringBuilder();
        for (Number j : a) {
            s.append(j).append("t");
        }
        System.out.println(s);
    }

    public String format_(String pattern, double data) {
        myFormat.applyPattern(pattern);
        return myFormat.format(data);
    }

    public int randint(int from, int to) {
        return from + (int) (r.nextInt(to - from));
    }

    public double randf(double from, double to) {
        return from + (to - from) * r.nextDouble();
    }

    
    public double randf_format(int n, double from, double to) {
        StringBuilder pattern = new StringBuilder("0.");
        pattern.append("0".repeat(n));
        String s = this.format_(pattern.toString(), randf(from, to));
        return Double.parseDouble(s);
    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/440039.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号