创建多线程的四种方法
继承Thread类
- 创建Thread的子类
- 重写run方法(将创建线程做的事情写入到run方法中)
- 创建Thread类的子类对象
- 调用start方法
package eur1ka;
/*
* 多线程创建:
* 方法1:继承Thread类
* 1. 创建Thread的子类
* 2. 重写run方法(将创建线程做的事情写入到run方法中)
* 3. 创建Thread类的子类对象
* 4. 调用start方法
*
*
*
* */
class MyThread extends Thread{
@Override
public void run() {
for(int i = 0; i<100;i++){
if(i%2==0){
System.out.println(i);
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
MyThread mythread = new MyThread();
mythread.start();
}
}
实现Runnable接口
- 创建一个实现了Runnable接口的类
- 实现类去实现Runnable中的抽象方法
- 创建实现类的对象
- 将此方法作为参数传递到Thread类的构造器中,创建Thread类的对象
- 通过Thread类的对象调用start()
package eur1ka;
/*
* 方法2:实现runnable接口
* 1. 创建一个实现了Runnable接口的类
* 2. 实现类去实现Runnable中的抽象方法
* 3. 创建实现类的对象
* 4. 将此方法作为参数传递到Thread类的构造器中,创建Thread类的对象
* 5. 通过Thread类的对象调用start()
* */
public class Thread1 {
public static void main(String[] args) {
Thread1Test test = new Thread1Test();
Thread t1 = new Thread(test);
t1.start();
}
}
class Thread1Test implements Runnable{
@Override
public void run() {
for(int i = 0; i<100; i++){
if(i%2==0){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
使用Callable接口
特点
相对于Runnable,可以有返回值
方法可以抛出异常
支持泛型返回值
需要借助Future Task类,比如获取返回结果
Future
创建方法
1.创建一个实现Callable接口的类
2.实现call方法。即需要执行的函数,call方法有返回值
3.创建Callable接口实现类对象
4.创建FutureTask对象并将实现 callable接口的类传入
5.将FutureTask对象作为参数传入Thread构造器中
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadNew1 {
public static void main(String[] args) {
Threadnew t = new Threadnew();
FutureTask ft = new FutureTask(t);
Thread t1 = new Thread(ft);
t1.start();
try{
Object sum = ft.get();
System.out.println(sum);
}catch (InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e){
e.printStackTrace();
}
}
}
class Threadnew implements Callable {
@Override
public Object call() throws Exception {
int sum = 0;
for(int i=0;i<100;i++){
if(i%2==0){
System.out.println(i);
sum+=i;
}
}
return sum;
}
}
使用线程池
相关API:ExecutorService,Executors
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new NumThread());//适合使用Runnable
// executorService.submit();//适合使用Callable
executorService.shutdown();
}
}
class NumThread implements Runnable{
@Override
public void run() {
for(int i = 0;i<100;i++){
if(i%2==0){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
多线程同步问题
方法1:同步监视器
synchronized(){}
需要监视的代码放到同步监视器中,与要注意的是同步监视器需要相同
方法2:同步方法
使用关键词synchronized声明为同步的
同步监视器
runnable接口
public class WindowsTest1 {
public static void main(String[] args) {
Windows1 w1 = new Windows1();
Thread t1 = new Thread(w1);
Thread t2 = new Thread(w1);
Thread t3 = new Thread(w1);
t1.start();
t2.start();
t3.start();
}
}
class Windows1 implements Runnable{
private int ticket=100;
@Override
public void run() {
synchronized (this){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while(ticket>0) {
System.out.println(Thread.currentThread().getName() + "=>当前票号为:" + ticket);
ticket--;
}
}
}
}
继承Thread类
public class WindowsTest3 {
public static void main(String[] args) {
Windows3 w1 = new Windows3();
Windows3 w2 = new Windows3();
Windows3 w3 = new Windows3();
w1.start();
w2.start();
w3.start();
}
}
class Windows3 extends Thread{
private static int ticket=100;
private static Object obj = new Object();
@Override
public void run() {
while(true){
synchronized (Windows3.class){
if(ticket>0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "=>当前票号为:" + ticket);
ticket--;
}else{
break;
}
}
}
}
}
同步方法
Runnable接口
public class WindowsTest2 {
public static void main(String[] args) {
Windows2 w1 = new Windows2();
Thread t1 = new Thread(w1);
Thread t2 = new Thread(w1);
Thread t3 = new Thread(w1);
t1.start();
t2.start();
t3.start();
}
}
class Windows2 implements Runnable{
private int ticket=100;
@Override
public void run() {
fun();
}
public synchronized void fun(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while(ticket>0) {
System.out.println(Thread.currentThread().getName() + "=>当前票号为:" + ticket);
ticket--;
}
}
}
继承Thread类
public class WindowsTest4 {
public static void main(String[] args) {
Windows4 w1 = new Windows4();
Windows4 w2 = new Windows4();
Windows4 w3 = new Windows4();
w1.start();
w2.start();
w3.start();
}
}
class Windows4 extends Thread{
private static int ticket=100;
private static Object obj = new Object();
@Override
public void run() {
while(true){
fun();
}
}
public static synchronized void fun(){
while(ticket>0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "=>当前票号为:" + ticket);
ticket--;
}
}
}
实例化ReentrantLock
- 实例化reentrantlock
- 调用lock方法
- 解锁
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
Windows w1 = new Windows();
Thread t1 = new Thread(w1);
Thread t2 = new Thread(w1);
Thread t3 = new Thread(w1);
t1.start();
t2.start();
t3.start();
}
}
class Windows implements Runnable{
private int ticket = 100;
// 实例化reentrantlock
private ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
try{
//调用lock方法
lock.lock();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while(ticket>0) {
System.out.println(Thread.currentThread().getName() + "=>当前票号为:" + ticket);
ticket--;
}
}finally {
//解锁
lock.unlock();
}
}
}