线程:多线程
进程:可以并行操作的。一个应用程序至少有一个进程。
进程与进程之间的通讯,是通过系统级别,比较重量级的。每开一个进程,对操作系统来说,都是一个比较复杂和耗时的过程。
有一些程序需要并行执行,其原理是以空间换取时间。提高效率
一个进程可以有多个线程
至少有一个线程。创建和切换线程的开销要比进程小。
并行:物理真正多个cpu核心执行代码
并发:逻辑上多个线程。进程同时执行,时间片切换
使用多线程的两种方式:
1.继承Thread类,重写Run()方法。在run方法中编写业务逻辑。通过start方法启动。
package com.situ.chaoter1;
public class Test1 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(start);
// for(int i =0;i<10000;i++) {
// System.out.println(i);
// }
//第一种创建线程
Thread t1 = new MyThread(0,5000);
Thread t2 = new MyThread(5001,10000);
//启动线程
t1.start(); t2.start();
// long end = System.currentTimeMillis();
// System.out.println(end);//花费时间数(毫秒)
}
}
package com.situ.chaoter1;
public class MyThread extends Thread{
private int from;
private int to;
public MyThread(int from, int to) {
super();
this.from = from;
this.to = to;
}
@Override
public void run() {
for(int i =from;i<=to;i++) {
System.out.println(i);
}
System.out.println("------------------------");
System.out.println(System.currentTimeMillis());
}
}
执行结果:

一个线程会执行到一定程度换换下一个线程执行,执行多长时间看系统分配的时间片大小。
2.实现Runable接口,然后Thread = new Thread(new Taskable(0,2500));新建一个对象并给它指定方法。
package com.situ.chaoter1;
public class Mytask implements Runnable {
private int from;
private int to;
public Mytask(int from, int to) {
super();
this.from = from;
this.to = to;
}
@Override
public void run() {
for(int i =from ;i<=to;i++) {
System.out.println(i);
}
System.out.println();
System.out.println(System.currentTimeMillis());
}
}
package com.situ.chaoter1;
public class Test2 {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
//第二种创建线程的方法,推荐使用
Thread t1 = new Thread(new Mytask(0,2500));
Thread t2 = new Thread(new Mytask(2500,5000));
Thread t3 = new Thread(new Mytask(5000,7500));
Thread t4 = new Thread(new Mytask(7500,10000));
t1.start();
t2.start();
t3.start();
t4.start();
}
}
执行结果:

线程执行的结果通常是不可预料的。
线程出现问题,是由于多个线程在共享一个数据,如果线程不竞争数据,就不会出现问题。
同步和锁
锁:为了解决多线程并发访问资源的问题
在java中,锁是一个比较复杂的问题。
synchronized:重量级锁,可重入锁,但是线程的性能会下降,排它锁,性能弱,安全性最高
所有线程共用一把锁
两种用法:
1.synchronized(锁对象):同步块。同一时刻,只能有一个线程进入到同步块中。
package com.situ.chaoter3;
public class Test1 {
public static void main(String[] args) {
Task task = new Task();
for(int i = 0;i<100;i++) {
Thread t = new Thread(task);
t.start();
}
System.out.println("分配任务成功,开始执行!");
}
}
package com.situ.chaoter3;
public class Task implements Runnable{
private static byte[] lock = new byte[0];
public static int number = 0;
public boolean doSomeThing() {
synchronized (lock) {
number = ++number +1;
System.out.println(number);
if(number%2==1) {
System.out.println("--------------------------");
return true;
}
return false;
}
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.yield();
/*
* System.out.println(number); if(number%2==1) {
* System.out.println("--------------------------"); break; }
*/
//同步代码块
boolean b = doSomeThing();
if(b) {
break;
}
}
}
}
2将synchronized定义在方法的前面,则是以this为锁。
只需要将自己创建的静态锁删除,synchronized (this){}即锁定的模块。
package com.situ.chaoter3;
public class Task implements Runnable{
/* private static byte[] lock = new byte[0]; */
public static int number = 0;
public boolean doSomeThing() {
synchronized (this) {
number = ++number +1;
System.out.println(number);
if(number%2==1) {
System.out.println("--------------------------");
return true;
}
return false;
}
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.yield();
/*
* System.out.println(number); if(number%2==1) {
* System.out.println("--------------------------"); break; }
*/
//同步代码块
boolean b = doSomeThing();
if(b) {
break;
}
}
}
}
=======================================
其它解决方法
Timer: 定时器
Executors:工具类
ExecutorService:业务执行器
定时器:
package com.situ.chaoter4;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class Test1 {
public static void main(String[] args) {
//定时器
Timer timer = new Timer();
//创建一个定时任务
TimerTask tt = new MyTimerTask();
Calendar can = Calendar.getInstance();
can.set(Calendar.HOUR_OF_DAY,16);
can.set(Calendar.MINUTE, 30);
timer.schedule(tt, can.getTime());
}
}
package com.situ.chaoter4;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("时间到了!");
}
}

线程、线程池
package com.situ.chaoter4;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test2 {
public static void main(String[] args) {
//创建一个单线程
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new MyTimerTask());
//创建一个线程池
ExecutorService es1 = Executors.newCachedThreadPool();
for(int i = 0 ;i<5;i++) {
es1.submit(new MyTimerTask());
}
System.out.println("任务分配完毕!");
}
}

本文介绍了多线程编程的基础概念,如进程与线程的区别,如何通过继承Thread或实现Runnable创建线程,并重点讲解了Java中的锁和synchronized同步机制。实例演示了使用synchronized关键字和this作为锁的不同场景。此外,还提及了定时器和线程池在并发编程中的应用。
6501

被折叠的 条评论
为什么被折叠?



