Java小记 多线程

这两篇文章写得真的好:



两种实现方式:

  • 继承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<Integer> 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<Integer> itr = list.iterator();
            while(itr.hasNext())
            {
                int data = itr.next();
                sum += data;
                if(data>max)
                {
                    max = data;
                }
                if(data<min)
                {
                    min = data;
                }
            }
        }
    }

    public static void mk_list()
    {
        for(int i=0;i<40;i++)
        {
            list.add(tool.randint(20, 200));
        }
    }

    public static void main(String[] args) throws Exception
    {
        Thread t1 = new Thread(new TrySome("Fry", "Hello future!"));
        Thread t2 = new Thread(new TrySome("Bender", "Bite my shiny metal ass!"));
        t1.start();t2.start();t2.join();
        out.println(value);
        // ==========================================
        out.println("average: "+ (sum/80) + "  max:" + max + "  min: " + min);
    }
}
import static java.lang.System.out;
import java.util.*;
import Tools.Tools;

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

    }

    public static List<Double> mk_list()
    {
        List<Double> 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;

/*****************************************************************
 * ****** 属性 *******
 * - d : Date()
 * - r : Random()
 * - myFormat : DecimalFormat()
 *
 * --------方法-------------
 * print(Number...) | print(String)
 * format_(pattern, data)
 * randint(from, to) | randf(from, to)
 * randf_format(n, from, to)  -- 小数位数 n 位
 *
 *
 ******************************************************************/
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();
    }

    /***********************************************
     // return double
     // n:小数位数 from ~ to
     ************************************************/
    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);
    }

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的壳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值