线程
1.基本概念
多线程是实现并发机制的一种有效手段。进程和线程一样,都是实现并发的一个基本单位。线程是比进程更小的执行单位,线程是进程的基础之上进行进一步的划分。所谓多线程是指一个进程在执行过程中可以产生多个更小的程序单元,这些更小的单元称为线程,这些线程可以同时存在,同时运行,一个进程可能包含多个同时执行的线程。
2.Java中的线程
方法1
继承了Thread类就可以当线程使用
class Cat extends Thread{
int times = 0;
@Override
public void run() {
while (times < 10) {
times++;
System.out.println("kakaka" + times);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
直接调用Run方法不会开启新线程
调用Cat实例类的start()方法,就会从JVM层级开启新线程
方法2
实现Runnable接口,并传入Thread()构造器
class Thread2 implements Runnable {
int i = 0;
@Override
public void run() {
while (i < 10){
try {
System.out.println("current thread is " + Thread.currentThread().getName());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread2 t = new Thread2();
Thread tt = new Thread(t);
t.run();
}
}
下面是多线程卖票问题,发现并发问题,ticket_num判断导致的
stop停止功能
public class ticket {
public static void main(String[] args) {
seller s1 = new seller();
seller s2 = new seller();
seller s3 = new seller();
s1.start();
s2.start();
s3.start();
Thread.sleep(4000);
s1.stopsell();
}
}
class seller extends Thread {
static int ticket_num = 100;
static boolean sellable = true;
@Override
public void run() {
while (ticket_num > 0 && sellable){
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "卖票一张,还剩" + --ticket_num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopsell(){
sellable = false;
}
}
子线程让位主线程,在a线程调用b线程.join,会让b线程先运行完
public class Thread3 {
public static void main(String[] args) throws InterruptedException {
int j = 0 ;
Thread t = new Thread(new t1());
t.start();
while (j < 20){
System.out.println("主线程" + ++j);
Thread.sleep(1000);
if (j == 4){
t.join();
}
}
}
}
class t1 implements Runnable{
int i = 0;
@Override
public void run() {
while (i <= 20){
System.out.println("子线程安排" + ++i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
守护线程
作用相当于主线程的保姆,主线程完事,守护线程也完事了。
public class MyDaemonThread {
public static void main(String[] args) {
DThread d = new DThread();
d.setDaemon(true);
d.start();
for(int i = 0; i <=50;i++){
System.out.println("主线程"+Thread.currentThread().getName());
}
}
}
class DThread extends Thread{
@Override
public void run() {
while (true){
System.out.println("守护线程安排"+ Thread.currentThread().getName());
}
}
}
1.new
2.(runnable)running
3.(runnable)ready
4.waiting
5.timed_waiting
6.terminated
线程同步机制
用static + synchronized 修饰卖方法
public class syn {
public static void main(String[] args) throws InterruptedException {
syn_seller s1 = new syn_seller();
syn_seller s2 = new syn_seller();
syn_seller s3 = new syn_seller();
s1.start();
s2.start();
s3.start();
}
}
class syn_seller extends Thread {
static int ticket_num = 100;
static boolean sellable = true;
@Override
public void run() {
sell();
}
public synchronized void sell() {
while (ticket_num > 0 && sellable){
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "卖票一张,还剩" + --ticket_num);
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "被中断了!!!!");
}
}
}
}
练习题1
练习题2
1答案
public class homework {
public static void main(String[] args) {
Thw1 t1 = new Thw1();
Thw2 t2 = new Thw2(t1);
t1.start();
t2.start();
}
}
class Thw1 extends Thread{
static Boolean running = true;
@Override
public void run() {
Random r = new Random();
while (running){
System.out.println(r.nextInt(100));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Thw2 extends Thread{
private Thw1 thw1;
private final Scanner scanner = new Scanner(System.in);
public Thw2(Thw1 thw1){
this.thw1 = thw1;
}
@Override
public void run() {
while (true){
char in = scanner.next().toUpperCase().charAt(0);
if(in == 'Q'){
Thw1.running = false;
break;
}
}
}
}
2答案
public class homework2 {
public static void main(String[] args) {
Account c1 = new Account(1);
Account c2 = new Account(2);
c1.start();
c2.start();
}
}
class Account extends Thread{
static int money = 10000;
Scanner s = new Scanner(System.in);
int clientNum;
public Account(int clientNum){
this.clientNum = clientNum;
}
@Override
public void run() {
while (true){
int i = s.nextInt();
if(i == clientNum){
withdraw();
}
}
}
public synchronized void withdraw(){
if(money <= 0){
System.out.println("余额不足");
}else {
System.out.println(Thread.currentThread().getName() + "取钱1000 , 余额: " + (money-=1000));
}
}
}