Multiple Thread (Runnable vs. Thread), Part 1

  1. Multi-threading states
  2. Java thread init methods
  3. Examples of Thread and Runnable

Multi-threading states

  1. new: 新建状态,保持这个状态直到程序start()
  2. ready: 调用了start(),就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度
  3. running: 获取了CPU资源,执行run()里面的指令
  4. suspend: 失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种
    • 等待阻塞: wait()
    • 同步阻塞: 线程在获取synchronized同步锁失败后
    • 其他阻塞: 其他阻塞:通过调用线程的sleep()或join()发出了I/O请求时,线程就会进入到阻塞状态
  5. dead: 一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态

Java thread init methods

Java 提供了三种创建线程的方法

  • 通过实现Runnable接口
  • 通过继承Thread类本身
  • 通过Callable和Future创建线程

Java thread example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// class extending Thread
import java.util.*;
// new class
class MyThread extends Thread {
private int ticket = 10;
private String name;
private Random rand = new Random();
// constructors
public MyThread(String name) {
this.name = name;
System.out.println(this.name + " starts with " + this.ticket + ".");
}
// Override the run function to implement functionality
@Override
public void run() {
for (int i = 0; i < 500; i++) {
if (this.ticket > 0) {
// create a random number between two sales
int nxt = rand.nextInt(20) * 10;
this.ticket--;
System.out.println(this.name + " sold a ticket, now has " + this.ticket + " tickets.");
try {
Thread.sleep(nxt);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Now, " + this.name + " has ended.");
}
}
// method to run the class above
public class ThreadDemo {
public static void main(String[] args) {
System.out.println("start");
MyThread mt1 = new MyThread("Counter 1");
MyThread mt2 = new MyThread("Counter 2");
MyThread mt3 = new MyThread("Counter 3");
mt1.start();
mt2.start();
mt3.start();
}
}

Runnable Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;
// now using Runnable interface instead of extending a class
public class MyRunnable implements Runnable{
private int ticket = 30;
private Random rand = new Random();
private Lock lock = new ReentrantLock();
public MyRunnable() {
System.out.println("This class starts with " + this.ticket + " tickets.");
}
// overriding the run method just as before
@Override
public void run() {
while (this.ticket > 0) {
// tryLock() checks if the lock is available, takes the lock and return true if yes, else return false
if (lock.tryLock()){
try {
// command to execute with the lock
System.out.println(Thread.currentThread().getName() + " acquired lock.");
this.ticket--;
System.out.println(Thread.currentThread().getName() + " sold a ticket, now has " + this.ticket + " tickets.");
} catch (Exception e) {
System.err.println(e);
} finally {
// releasing the lock
System.out.println(Thread.currentThread().getName() + " released lock.");
lock.unlock();
}
// wait for a random length after selling a ticket
int nxt = rand.nextInt(20) * 10;
try {
Thread.sleep(nxt);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// if lock is not available, wait
else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Now, " + Thread.currentThread().getName() + " has ended.");
}
}

Django Basics, Part 1

Django directory levels

  1. manage.py: we use this to communicate with Django server
  2. project directory:
    1. __init__.py: tells Django to use directory as a python package
    2. settings.py: Django configuration file
    3. urls.py: url schema
    4. wsgi.py: project and wsgi integration web server

Database (MySQL) config

  • dependencies used:
    mysql 5.7.24 h56848d4_0
    mysql-connector-c 6.1.11 hccea1a4_0
    mysql-connector-python 8.0.17 py27h3febbb0_0 anaconda
    mysql-python 1.2.5 py27h1de35cc_0 anaconda
    pymysql 0.9.3 py27_0
  • __init__.py:, add the following code:
    1
    2
    import pymysql
    pymysql.install_as_MySQLdb()
  • in settings.py: add database configurations to connect to the database
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': # server name
    'USER': # user name
    'PASSWORD': # password
    'HOST': 'localhost',
    'PORT': '3306',
    }
    }

Init new application

  • init new application:
    1
    python manage.py startapp <myApp>
  • codes above creates:
    • admin.py: website config
    • models.py: model
    • views.py: view
  • In setting, add to INSTALLED_APP:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myApp'
    ]

models.py file

  • the following is an example of models.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models

    # Create your models here.
    class Grades(models.Model):
    gname = models.CharField(max_length=20)
    gdate = models.DateTimeField()
    ggirlnum = models.IntegerField()
    gboynum = models.IntegerField()
    isDelete = models.BooleanField(default=False)

    def __str__(self):
    return "%s-%d-%d"%(self.gname, self.gboynum, self.ggrilnum)


    class Students(models.Model):
    sname = models.CharField(max_length=20)
    sgender = models.BooleanField(default=True)
    sage = models.IntegerField()
    scontend = models.CharField(max_length=20)
    isDelete = models.BooleanField(default=False)
    sgrade = models.ForeignKey("Grades")

    def __str__(self):
    return "%s-%d-%s"%(self.sname, self.sage, self.scontend)
  • make migration and execute migration file: will create database according to models.py
    1
    2
    python manage.py makemigrations # create migration file
    python manage.py migrate # execute migration file

To add new entries with manage.py shell commands

  1. enter shell:
    1
    python manage.py shell
  2. import packages in shell:
    1
    2
    3
    from myApp.models import Grades, Students
    from django.utils import timezone
    from datetime import *
  3. add new entry to db:
    1
    2
    3
    4
    5
    6
    grade1 = Grades()
    grade1.gname = "something"
    grade1.gdate = datetime(year=,month=,day=)
    grade1.ggirlnum = 70
    grade1.gboynum = 35
    grade1.save()
  4. some other command:
    1
    2
    3
    4
    5
    6
    Grades.objects.all()    # get all data entries in Grades
    g = Grades.objects.get(pk=1) # get the 1st object in Grades
    g.gboynum = 45
    g.save() # alternate existing data
    d.delete() # delete, including the one in db
    stu1 = g.students_set.create(sname=...) # add new student with one line

To run server

  • execute:
    1
    python manage.py runserver ip:port
  • Admin:
    • publish content
    • add/modify/delete content
    • add “‘django.contrib.admin’” in INSTALLED_APPS
    • exists by defualt
    • add “/admin” and log in
    • change language or timezone based on preference

(to be continued…)

Pictures from Yellowknife, Canada

Casually ice fishing
Casually ice fishing
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight
Northlight